I don't think you can actually have a time
data type that goes above 24 hours, so I have broken your time worked down into separate fields for you to do what you want with. You could do away with the cte
by just adding the big date case
statements into your group by
, but that would mean duplicated code and therefore duplicated effort to update it and I'm lazy:
declare @t table (EmpName nvarchar(10), WorkDate date, WorkTime time);
insert into @t values
('User1','20161018',NULL),('User1','20161020','06:00:38'),('User1','20161021','07:41:44'),('User1','20161024','06:35:53'),('User1','20161025','06:29:03'),('User1','20161026','07:25:09'),('User1','20161031','07:49:12'),('User1','20161103','09:23:05'),('User1','20161105',NULL),('User1','20161107','09:18:38'),('User1','20161108','09:16:01'),('User1','20161109','08:05:03'),('User1','20161111','09:00:43'),('User1','20161116','09:18:14');
with cte as
(
select EmpName
-- Pick the later of either the start of the current week or the current month.
,case when dateadd(wk, datediff(wk,0,WorkDate), 0) < dateadd(month,datediff(month,0,WorkDate),0)
then dateadd(month,datediff(month,0,WorkDate),0) -- This calculates the start of the month.
else dateadd(wk, datediff(wk,0,WorkDate), 0) -- This calculated the start of the week.
end as WeekStart
-- Pick the earlier of either the end of the current week or the current month.
,case when dateadd(d,6,dateadd(wk, datediff(wk,0,WorkDate), 0)) >= dateadd(month,datediff(month,0,WorkDate)+1,0)
then dateadd(d,-1,dateadd(month,datediff(month,0,WorkDate)+1,0)) -- This calculates the last day of the month.
else dateadd(d,6,dateadd(wk, datediff(wk,0,WorkDate), 0)) -- This calculates the last day of the week.
end as WeekEnd
-- Pick the earlier of either the friday of the current week or or the end of the current month.
,case when dateadd(d,4,dateadd(wk, datediff(wk,0,WorkDate), 0)) > case when dateadd(d,6,dateadd(wk, datediff(wk,0,WorkDate), 0)) >= dateadd(month,datediff(month,0,WorkDate)+1,0)
then dateadd(d,-1,dateadd(month,datediff(month,0,WorkDate)+1,0)) -- This calculates the last day of the month.
else dateadd(d,6,dateadd(wk, datediff(wk,0,WorkDate), 0)) -- This calculates the last day of the week.
end
then case when dateadd(d,6,dateadd(wk, datediff(wk,0,WorkDate), 0)) >= dateadd(month,datediff(month,0,WorkDate)+1,0)
then dateadd(d,-1,dateadd(month,datediff(month,0,WorkDate)+1,0)) -- This calculates the last day of the month.
else dateadd(d,6,dateadd(wk, datediff(wk,0,WorkDate), 0)) -- This calculates the last day of the week.
end
else dateadd(d,4,dateadd(wk, datediff(wk,0,WorkDate), 0)) -- This calculates the Friday of the week.
end as WorkingWeekEnd
,datepart(hour,WorkTime) as HoursWorked
,datepart(minute,WorkTime) as MinutesWorked
,datepart(second,WorkTime) as SecondsWorked
from @t
)
select EmpName
,WeekStart
,WeekEnd
,WorkingWeekEnd
,avg(datediff(d,WeekStart,WorkingWeekEnd)+1) * 8 as PlannedHoursWorked
,isnull(sum(HoursWorked),0) as HoursWorked
,isnull(sum(MinutesWorked),0) as MinutesWorked
,isnull(sum(SecondsWorked),0) as SecondsWorked
from cte
group by EmpName
,WeekStart
,WeekEnd
,WorkingWeekEnd
order by EmpName
,WeekStart;
Output:
╔═════════╦═════════════════════════╦═════════════════════════╦═════════════════════════╦════════════════════╦═════════════╦═══════════════╦═══════════════╗
║ EmpName ║ WeekStart ║ WeekEnd ║ WorkingWeekEnd ║ PlannedHoursWorked ║ HoursWorked ║ MinutesWorked ║ SecondsWorked ║
╠═════════╬═════════════════════════╬═════════════════════════╬═════════════════════════╬════════════════════╬═════════════╬═══════════════╬═══════════════╣
║ User1 ║ 2016-10-17 00:00:00.000 ║ 2016-10-23 00:00:00.000 ║ 2016-10-21 00:00:00.000 ║ 40 ║ 13 ║ 41 ║ 82 ║
║ User1 ║ 2016-10-24 00:00:00.000 ║ 2016-10-30 00:00:00.000 ║ 2016-10-28 00:00:00.000 ║ 40 ║ 19 ║ 89 ║ 65 ║
║ User1 ║ 2016-10-31 00:00:00.000 ║ 2016-10-31 00:00:00.000 ║ 2016-10-31 00:00:00.000 ║ 8 ║ 7 ║ 49 ║ 12 ║
║ User1 ║ 2016-11-01 00:00:00.000 ║ 2016-11-06 00:00:00.000 ║ 2016-11-04 00:00:00.000 ║ 32 ║ 9 ║ 23 ║ 5 ║
║ User1 ║ 2016-11-07 00:00:00.000 ║ 2016-11-13 00:00:00.000 ║ 2016-11-11 00:00:00.000 ║ 40 ║ 35 ║ 39 ║ 85 ║
║ User1 ║ 2016-11-14 00:00:00.000 ║ 2016-11-20 00:00:00.000 ║ 2016-11-18 00:00:00.000 ║ 40 ║ 9 ║ 18 ║ 14 ║
╚═════════╩═════════════════════════╩═════════════════════════╩═════════════════════════╩════════════════════╩═════════════╩═══════════════╩═══════════════╝