I am working in HRMS. My problem is in vacation,
If an employee take vacation from 19/3/2014 to 5/4/2014 application calculates that he take 18 days in month instead of 3 days.
I store vacations in vacation table
columns :
emp_id | vac_type | from | to
Now, How can I make query to tell me that he take 13 days in March and 5 days in April?
Excellent question! I was able to find a way to do it, but I did have to use slightly different notation for the dates (see below).
DECLARE #startDate DATETIME, #endDate DATETIME, #lastDayOfStartMonth INT
SET #startDate = '3/19/2014'
SET #endDate = '4/5/2014'
SELECT #lastDayOfStartMonth =
1+DATEPART(dd, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#startDate)+1,0)))
SELECT DATENAME(month, #startDate) AS [Month],
#lastDayOfStartMonth - DATEPART(dd, #startDate) AS [DaysSpent],
DATENAME(month, #endDate) AS [Month],
DATEPART(dd, #endDate) AS [DaysSpent]
Output:
| Month | DaysSpent | Month | DaysSpent |
|-------|-----------|-------|-----------|
| March | 13 | April | 5 |
SQL Fiddle example
My work here was based on the design from Pinal Dave's post SQL SERVER – Find Last Day of Any Month – Current Previous Next
Handling dates over more than two months
DECLARE #startDate DATETIME, #endDate DATETIME, #currentDate DATETIME, #currentDay INT
DECLARE #currentMonth INT, #lastDayOfStartMonth INT
CREATE TABLE #VacationDays ([Month] VARCHAR(10), [DaysSpent] INT)
SET #startDate = '1/19/2014'
SET #endDate = '4/5/2014'
SET #currentMonth = DATEPART(mm, #startDate)
SET #currentDay = DATEPART(dd, #startDate)
SET #currentDate = #startDate
WHILE #currentMonth < DATEPART(mm, #endDate)
BEGIN
SELECT #lastDayOfStartMonth =
DATEPART(dd, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#currentDate)+1,0)))
PRINT #lastDayOfStartMonth
INSERT INTO #VacationDays
SELECT DATENAME(month, #currentDate) AS [Month],
#lastDayOfStartMonth - #currentDay + 1 AS [DaysSpent]
SET #currentDate = DATEADD(mm, 1, #currentDate)
SET #currentMonth = #currentMonth + 1
SET #currentDay = 1
END
IF DATEPART(mm, #startDate) = DATEPART(mm, #endDate)
BEGIN
INSERT INTO #VacationDays
SELECT DATENAME(month, #endDate) AS [Month],
DATEPART(dd, #endDate) - DATEPART(dd, #startDate) + 1 AS [DaysSpent]
END
ELSE
BEGIN
INSERT INTO #VacationDays
SELECT DATENAME(month, #endDate) AS [Month],
DATEPART(dd, #endDate) AS [DaysSpent]
END
SELECT * FROM #VacationDays
DROP TABLE #VacationDays
Output:
| Month | DaysSpent |
|----------|-----------|
| January | 13 |
| February | 28 |
| March | 31 |
| April | 5 |
SQL Fiddle example - It takes about a minute to run. It's much faster running in a local instance of SSMS.
Here's how it works
For the example below I am using a #startDate value of 05-05-2015.
The value of CAST(0 AS DATETIME) is the date 1900-01-01, so that means the line DATEDIFF(m,0,#startDate) is essentially asking, how many months have passed since January 1, 1900? For this example, that value is 1384.
DATEADD(mm, DATEDIFF(m,0,#startDate)+1,0) or DATEADD(mm, 1384+1,0) is saying, Add 1385 months to the date value 0 (or 1900-01-01). This will give us the DATETIME value of the first of the month after #startDate's month. For our example, 2015-06-01.
DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#startDate)+1,0)) or DATEADD(s,-1,'2015-06-01') subtracts 1 second from the first of next month, give us the last second of the current month, or 2015-05-31 23:59:59.
Then we use DATEPART to get the day value of that date: 31.
31 is the last day in May.
I don't know how to do this directly in SQL using a SQL query. But if you have the start and end dates of the vacation in your C# code, then you could calculate the number of days of vacation occurring in each month by doing something like the following. This got a little more complicated than I had intended, but it's the best I could come up with. For your example, this code produces the following output:
Vacation days in March: 13 days
Vacation days in April: 5 days
Code:
class Program
{
class DateRange
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
static void Main(string[] args)
{
DateRange vacation = new DateRange();
vacation.Start = new DateTime(2014, 3, 19);
vacation.End = new DateTime(2014, 4, 5);
// Assuming April 5 represents the last day of vacation, let's
// add one to it, to show that his vacation actually ends on the
// following day.
vacation.End = vacation.End.AddDays(1);
DateRange currentMonth = new DateRange();
currentMonth.Start = new DateTime(vacation.Start.Year, vacation.Start.Month, 1);
currentMonth.End = currentMonth.Start.AddMonths(1);
while (currentMonth.Start < vacation.End)
{
Console.WriteLine("Vacation days in {0}: \t{1} days",
currentMonth.Start.ToString("MMMM"),
IntersectDates(currentMonth, vacation));
currentMonth.Start = currentMonth.Start.AddMonths(1);
currentMonth.End = currentMonth.End.AddMonths(1);
}
}
// Returns the number of days represented by the intersection of the two
// date ranges.
static int IntersectDates(DateRange dateRange1, DateRange dateRange2)
{
DateTime startOfIntersection = MaxDate(dateRange1.Start, dateRange2.Start);
DateTime endOfIntersection = MinDate(dateRange1.End, dateRange2.End);
return (startOfIntersection < endOfIntersection) ?
(int)(endOfIntersection - startOfIntersection).TotalDays :
0;
}
static DateTime MinDate(DateTime d1, DateTime d2)
{
return (d1 < d2) ? d1 : d2;
}
static DateTime MaxDate(DateTime d1, DateTime d2)
{
return (d1 > d2) ? d1 : d2;
}
}
DECLARE #FromDate date = '2014-03-19', #ToDate date = '2014-05-04'
WITH CTE AS
(
SELECT
YEAR(#FromDate) * 100 + MONTH(#FromDate) AS Month,
DATEADD(DAY, -DAY(#FromDate) + 1, #FromDate) AS FirstDateOfMonth,
DATEADD(DAY, -1, DATEADD(MONTH, 1, DATEADD(DAY, -DAY(#FromDate) + 1, #FromDate))) AS LastDateOfMonth
UNION ALL
SELECT
YEAR(DATEADD(MONTH, 1, FirstDateOfMonth)) * 100 + MONTH(DATEADD(MONTH, 1, FirstDateOfMonth)) AS Month,
DATEADD(MONTH, 1, FirstDateOfMonth),
DATEADD(DAY, -1, DATEADD(MONTH, 2, FirstDateOfMonth))
FROM CTE
WHERE #ToDate >= LastDateOfMonth
)
SELECT
*,
CASE
-- Same month
WHEN YEAR(#FromDate) * 100 + MONTH(#FromDate) = YEAR(#ToDate) * 100 + MONTH(#ToDate) THEN DATEDIFF(DAY, #FromDate, #ToDate) + 1
-- Get day from vacation start date to last date of month
WHEN Month = YEAR(#FromDate) * 100 + MONTH(#FromDate) THEN DATEDIFF(DAY, #FromDate, LastDateOfMonth) + 1
-- Get day from first date of month to vacation end date
WHEN Month = YEAR(#ToDate) * 100 + MONTH(#ToDate) THEN DATEDIFF(DAY, FirstDateOfMonth, #ToDate) + 1
-- Full month day
ELSE DATEDIFF(DAY, FirstDateOfMonth, LastDateOfMonth) + 1
END AS Day
FROM CTE
Result
Month FirstDateOfMonth LastDateOfMonth Day
----------- ---------------- --------------- -----------
201403 2014-03-01 2014-03-31 13
201404 2014-04-01 2014-04-30 30
201405 2014-05-01 2014-05-31 4
For applications like these, a dates table can greatly simplify queries at a reasonable cost to performance. It becomes nothing more than
SELECT emp_id, d.month, COUNT(*) as days
FROM Vacations v
INNER JOIN dates d on d.theDate BETWEEN v.Start and v.End
GROUP BY emp_id, d.month
See Create Date Dimension Table in SQL Server for an example of how to create a dates table.
This also simplifies complicated queries like the number of business days in a vacation:
SELECT emp_id, COUNT(*) as days
FROM Vacations v
INNER JOIN dates d on d.theDate BETWEEN v.Start and v.End
WHERE d.IsWeekend = 0
GROUP BY emp_id
Or grouping by pay-period or quarter:
SELECT emp_id, d.year, d.quarter, COUNT(*) as days
FROM Vacations v
INNER JOIN dates d on d.theDate BETWEEN v.Start and v.End
GROUP BY emp_id, d.year, d.quarter
I create a query that needs a calendar that I make it in WITH statement, In this calendar you can set your month names and month days -for a leap year-.
The calendar will be flexible for any year that used in vacation table -that automatically generate the correct dates for leap years-, Also support vacations starts from one year to next year.
;WITH calendar AS (
SELECT years.[Year], months.monthId, months.[monthName],
CASE ISDATE(CONVERT(varchar, years.[Year])+'-'+CONVERT(varchar,months.monthId)+'-'+CONVERT(varchar,months.monthDays))
WHEN 1 THEN months.monthDays
ELSE months.monthDays-1
END AS monthDays,
CONVERT(datetime, (CONVERT(varchar, years.[Year])+'-'+CONVERT(varchar,months.monthId)+'-1')) AS startDay,
CASE ISDATE(CONVERT(varchar, years.[Year])+'-'+CONVERT(varchar,months.monthId)+'-'+CONVERT(varchar,months.monthDays))
WHEN 1 THEN CONVERT(datetime, CONVERT(varchar, years.[Year])+'-'+CONVERT(varchar,months.monthId)+'-'+CONVERT(varchar,months.monthDays))
ELSE CONVERT(datetime, CONVERT(varchar, years.[Year])+'-'+CONVERT(varchar,months.monthId)+'-'+CONVERT(varchar,months.monthDays-1))
END AS EndDay
FROM
(SELECT DISTINCT YEAR(vi.[from]) As [Year] FROM vacation vi
UNION
SELECT DISTINCT YEAR(vi.[to]) As [Year] FROM vacation vi
) As years
CROSS JOIN
(SELECT 1 As monthId, 31 As monthDays, 'January' As [monthName] UNION ALL
SELECT 2, 29, 'February' UNION ALL
SELECT 3, 31, 'March' UNION ALL
SELECT 4, 30, 'April' UNION ALL
SELECT 5, 31, 'May' UNION ALL
SELECT 6, 30, 'June' UNION ALL
SELECT 7, 31, 'July' UNION ALL
SELECT 8, 31, 'August' UNION ALL
SELECT 9, 30, 'September' UNION ALL
SELECT 10, 31, 'October' UNION ALL
SELECT 11, 30, 'November' UNION ALL
SELECT 12, 31, 'December' ) As months
)
SELECT c.[year], c.monthId, c.[monthName],
CASE
WHEN v.emp_id IS NULL THEN 0
WHEN c.monthId = MONTH(v.[from]) THEN DATEDIFF(DAY, v.[from], c.EndDay) + 1
WHEN c.monthId = MONTH(v.[to]) THEN DATEDIFF(DAY, c.startDay, v.[to]) + 1
WHEN c.monthId BETWEEN MONTH(v.[from]) AND MONTH(v.[to]) THEN c.monthDays
END As vacationDays,
CASE
WHEN v.emp_id IS NULL THEN c.monthDays
WHEN c.monthId = MONTH(v.[from]) THEN DATEDIFF(DAY, c.startDay, v.[from])
WHEN c.monthId = MONTH(v.[to]) THEN DATEDIFF(DAY, v.[to], c.EndDay)
WHEN c.monthId BETWEEN MONTH(v.[from]) AND MONTH(v.[to]) THEN 0
END As nonvacationDays,
c.monthDays
FROM
calendar c
LEFT JOIN
vacation v ON c.monthId BETWEEN MONTH(v.[from]) AND MONTH(v.[to])
The result will be like this:
year | monthId | monthName | vacationDays | nonvacationDays | monthDays
-----+---------+-----------+--------------+-----------------+------------
2014 | 1 | January | 0 | 31 | 31
2014 | 2 | February | 0 | 28 | 28
2014 | 3 | March | 13 | 18 | 31
2014 | 4 | April | 5 | 25 | 30
2014 | 5 | May | 0 | 31 | 31
--....
Related
what I want to do is insert data in crystal report, the challenge is on how can I achieve that.
my data is
Jan 1, Number, Name
Jan 2, Number, Name
Jan 4, Number, Name
Jan 5, Number, Name
Jan 7, Number, Name
what I want to do is regardless of my data, I want to display in my crystal report the whole month.
so the expected output is
Jan 1, Number, Name
Jan 2, Number, Name
Jan 2, Null, Null
Jan 4, Number, Name
Jan 5, Number, Name
Jan 2, Null, Null
Jan 7, Number, Name
Jan 8, Null , Null
...
Jan 31, Null , Null
,is it possible to do this on crystal report?
I can generate it using select * from my queries, but i dont know how to fill in the missing values.
I think you need to create a date table once for the dates you need, then you can join to your data.
Ex. select * from [DateTable] left outer join [your queries] on [DateTable].date=[your queries].date
Here is an example how to create date table once for 10 years period starting from the current year:
DECLARE #StartDate date = '20210101';
DECLARE #CutoffDate date = DATEADD(DAY, -1, DATEADD(YEAR, 10, #StartDate));
;WITH seq(n) AS
(
SELECT 0 UNION ALL SELECT n + 1 FROM seq
WHERE n < DATEDIFF(DAY, #StartDate, #CutoffDate)
),
d(d) AS
(
SELECT DATEADD(DAY, n, #StartDate) FROM seq
),
src AS
(
SELECT
TheDate = CONVERT(date, d),
TheDay = DATEPART(DAY, d),
TheDayName = DATENAME(WEEKDAY, d),
TheWeek = DATEPART(WEEK, d),
TheISOWeek = DATEPART(ISO_WEEK, d),
TheDayOfWeek = DATEPART(WEEKDAY, d),
TheMonth = DATEPART(MONTH, d),
TheMonthName = DATENAME(MONTH, d),
TheQuarter = DATEPART(Quarter, d),
TheYear = DATEPART(YEAR, d),
TheFirstOfMonth = DATEFROMPARTS(YEAR(d), MONTH(d), 1),
TheLastOfYear = DATEFROMPARTS(YEAR(d), 12, 31),
TheDayOfYear = DATEPART(DAYOFYEAR, d)
FROM d
)
SELECT * into dbo.DateTable
FROM src
ORDER BY TheDate
OPTION (MAXRECURSION 0);
This is my first post so if I do anything incorrectly concerning the post please correct me.
I am creating a scoring program for a fishing competition.
I have the following tables(I am only going to list the columns of interest:
tblScores:
|Column Name|
Pk_CatchID
Fk_AnglerID
Day
Fk_FishID
Points
tblAnglers:
|Column Name|
Pk_AnglerID
Fk_BoatID
Name
tblBoats:
|Column Name|
Pk_BoatID
BoatName
Now what I want to do is create a score sheet for a whole week of competition, which is 5 days. So I have to do a sum of the scores and use the respective foreign keys to sum the scores for each boat.
This is what I have currently:
Select BoatName, " +
"Sum(tblScores.Points) AS [Day 1] " +
"from tblScores INNER JOIN tblAnglers ON tblScores.Fk_AnglerID=tblAnglers.Pk_AnglerID " +
" INNER JOIN tblBoats ON tblAnglers.Fk_BoatID=tblBoats.Pk_BoatID "
+ " where Day=1 GROUP BY BoatName
This works perfectly fine for one day, but what I would like to do is view this data in a DataGridView with columns for each day and then a total column as well.
Something like this:
|Boat Name|Day 1|Day 2|Day 3|Day 4|Day 5|Total|
|Example1 | 50 | 30 | 65 | 35 | 40 | 220 |
|Example2 | 40 | 50 | 70 | 35 | 30 | 225 |
I have tried using nested selects but I could not get this to work. I am open to suggestions on how this can be solved.
Also my other thought was to create a new table and keep these scores for each day in there(or even in the boats table) but I feel that the structure of the database would not be as good as data would be repeated. But I could be wrong.
Thank you all!
Also: I am using Visual Studio 2013 (C#) and Microsoft SQL Server 2010.
Try this:
Select
BoatName,
Sum(Case When Day = 1 Then tblScores.Points Else 0 End) AS [Day1],
Sum(Case When Day = 2 Then tblScores.Points Else 0 End) AS [Day2],
Sum(Case When Day = 3 Then tblScores.Points Else 0 End) AS [Day3],
Sum(Case When Day = 4 Then tblScores.Points Else 0 End) AS [Day4],
Sum(Case When Day = 5 Then tblScores.Points Else 0 End) AS [Day5],
Sum(tblScores.Points) As Total
From tblScores
INNER JOIN tblAnglers ON tblScores.Fk_AnglerID=tblAnglers.Pk_AnglerID
INNER JOIN tblBoats ON tblAnglers.Fk_BoatID=tblBoats.Pk_BoatID
GROUP BY BoatName
Order By BoatName
Fiddle
I'm looking for a fast and easy SQL Query to get records year by year, month by month and day by day.
My database example:
ID - DATE - CatID - VALUE
1 - 2013-08-06 - 32 - 243
2 - 2013-08-16 - 2 - 45
3 - 2013-08-21 - 2 - 1
4 - 2013-08-05 - 32 - 450
5 - 2013-08-05 - 32 - 449
6 - 2013-08-05 - 32 - 11
7 - 2013-08-01 - 2 - 221
8 - 2013-08-02 - 32 - 0
9 - 2013-08-02 - 32 - 0
10 - 2013-08-02 - 32 - 987
...
..
I have over 2 millions records on this table.
First:
I would like to get CatID = 32 and single/higher record of the day.
Result:
1 - 2013-08-06 - 32 - 243
4 - 2013-08-05 - 32 - 450
10 - 2013-08-02 - 32 - 987
Second:
I would like to get as same but by MONTH.
How can I do it with SQL SERVER. Currently Sql Server 2012.
Also using C# 5 and if you want to use, EF 6.
Down voters, this question became "popular question". Now please explain why down voted?
The below assumes that you want more than just the max value for each date/month, but also want to know the id of that row, etc, etc.
For daily...
WITH
sorted AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY CatID,
Date
ORDER BY Value DESC) AS ordinal_cat_date
FROM
yourTable
)
SELECT
*
FROM
sorted
WHERE
ordinal_cat_date = 1
AND catID = 32
For monthly...
WITH
sorted AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY CatID,
DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)
ORDER BY Value DESC) AS ordinal_cat_month
FROM
yourTable
)
SELECT
*
FROM
sorted
WHERE
ordinal_cat_month = 1
AND catID = 32
In both cases the ROW_NUMBER() function creates a sequence of numbers (1,2,3,4,etc) for each PARTITION of catID, date, in descending order of value. Whichever row has a value of 1 is the row with the highest value in that partition.
The formula DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0) just rounds the Date down to the first day of the month, thereby creating partitions for whole months.
Some other options that bring through multiple rows per day/month if those rows all share the same highest value...
SELECT -- Daily Version
*
FROM
yourTable
WHERE
NOT EXISTS (SELECT *
FROM yourTable AS lookup
WHERE lookup.CatID = yourTable.CatID
AND lookup.Value > yourTable.Value
AND lookup.Date = yourTable.Date
)
AND CatID = 32
SELECT -- Monthly Version
*
FROM
yourTable
WHERE
NOT EXISTS (SELECT *
FROM yourTable AS lookup
WHERE lookup.CatID = yourTable.CatID
AND lookup.Value > yourTable.Value
AND lookup.Date >= DATEADD(MONTH, DATEDIFF(MONTH, 0, yourTable.Date), 0)
AND lookup.Date < DATEADD(MONTH, 1+DATEDIFF(MONTH, 0, yourTable.Date), 0)
)
AND CatID = 32
Or possibly...
SELECT -- Daily Version
*
FROM
yourTable
INNER JOIN
(
SELECT
Date,
CatID,
MAX(Value) AS max_value
FROM
yourTable
GROUP BY
CatID,
Date
)
AS lookup
ON yourTable.Date = lookup.Date
AND yourTable.CatID = lookup.CatID
AND yourTable.Value = lookup.max_value
WHERE
yourTable.CatID = 32
SELECT -- Monthly Version
*
FROM
yourTable
INNER JOIN
(
SELECT
CatID,
DATEADD(MONTH, DATEDIFF(MONTH, 0, yourTable.Date), 0) AS month_start,
MAX(Value) AS max_value
FROM
yourTable
GROUP BY
CatID,
DATEADD(MONTH, DATEDIFF(MONTH, 0, yourTable.Date), 0)
)
AS lookup
ON yourTable.Date >= lookup.month_start
AND yourTable.Date < DATEADD(MONTH, 1, lookup.month_start)
AND yourTable.CatID = lookup.CatID
AND yourTable.Value = lookup.max_value
WHERE
yourTable.CatID = 32
I want to select a result from student table-
query -
if I pass any year like 2013 then select the students join start date and end date or he is currently there
in between these year
like if any student start date year is 2010 and end date year is 2013
and I select 2011 year then show this student record also .
Table structure is-
StudentID Age startDate EndDate
1 14 5/05/2013 7/05/2013
4 17 4/04/2012 8/10/2012
and I'm trying this-
select * from tblstudent
Where DATEPART(year, StartDate) BETWEEN #year-1 AND #year
Thanks in advance.
Not sure if I understood you, but this should do the job:
select *
from tblStudent s
where #year >= DATEPART(year, StartDate) and #year <= DATEPART(year, EndDate)
Actually, you almost there.
You just need to compare year part of your StartDate is smaller or equal to your #year and year part of your EndDate is bigger or equal to your #year.
Try like this;
select *
from tblStudent
where DATEPART(year, startDate) <= #year and DATEPART(year, EndDate) >= #year
For #year = 2013, output will be;
| STUDENTID | AGE | STARTDATE | ENDDATE |
------------------------------------------------------------------------------
| 1 | 14 | May, 05 2013 03:00:00+0000 | July, 05 2013 03:00:00+0000 |
Here SQL Fiddle Demo.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
we are using Punch Machine for Attendance with zkemkeeper.dll and geting AttLog using Vs.net 2010.How can Get Records from SQL Query?
my table structure like this
LogID int P.K.
DeviceIP varchar
EnrollNo int
AttDate datetime
AttYear int
AttMonth int
AttDay int
AttTime varchar
My current output:
LogID EnrollNo AttDate AttYear AttMonth AttDay AttTime
1 319 1/9/2011 9:55:00 PM 2011 8 31 9:55
2 319 1/9/2011 18:30:00 PM 2011 8 31 18:30
3 325 1/9/2011 10:00:00 PM 2011 8 31 10:00
4 325 1/9/2011 18:35:00 PM 2011 8 31 18:35
I want the new output like this with calculation of in-out time difference:
LogID EnrollNo AttDate AttYear AttMonth AttDay In out Diff
1 319 1/9/2011 9:55:00 PM 2011 8 31 9:55 18:30 8:35
2 325 1/9/2011 6:30:00 PM 2011 8 31 10:00 18:35 8:35
declare #t table (EnrollNo int, [Date] datetime, Time varchar(5))
insert #t select 1, '8-10-2011 12:00:32', '13:12'
union all select 1, '8-10-2011 12:00:32', '23:14'
union all select 2, '8-10-2011 12:00:32', '11:12'
union all select 2, '8-10-2011 12:00:32', '20:14'
union all select 3, '8-10-2011 12:00:35', '12:12'
union all select 3, '8-10-2011 12:00:32', '23:14'
union all select 4, '8-10-2011 12:00:32', '17:12'
union all select 4, '8-10-2011 12:00:32', '23:14'
select
EnrollNo,
CAST(CONVERT(varchar, Date, 101) AS DateTime),
right('0' + cast(datediff(hour, cast(min(Time) as datetime),
cast(max(Time) as datetime)) as varchar(2)),2) + ':' +
right('0' + cast(datediff(minute, cast(min(Time) as datetime),
cast(max(Time) as datetime)) % 60 as varchar(2)),2),
min(Time),
max(Time)
from #t group by EnrollNo,CAST(CONVERT(varchar, Date, 101) AS DateTime)
Try this...
SELECT TIMEDIFF("18:30","9:55") as Diff;
or
SELECT TIMEDIFF(In,Out) as Diff;
Output: 08:35:00
Do you want the first and last times for the same EnrolNo on the same day? Try a Group By to get you 'In' and 'Out' fields, then use the timediff from other answers to calculate the difference:
SELECT EnrolNo, AttYear, AttMonth, AttDay, Min(AttDate) AS [In], Max(AttDate) AS [Out],
TIME_Format(TIMEDIFF([Out],[In]),'%H:%i') As [Diff]
FROM Table
GROUP BY EnrolNo, AttYear, AttMonth, AttDay;