I have one time sheet table when i fetch the records it will display like this for one week.
This record is from one week from June 10 to June 16
EmpId Monday Tuesday Wednesday Thursday Friday Saturday Sunday StartDate EndDate
1 08:00 08:12 00:00 04:00 00:00 03:00 00:00 05/10/2013 05/16/2013
Need the output like this
Empid Monday startdate EndDate
1 08:00 05/10/2013 05/10/2013
1 08:12 05/11/2013 05/11/2013
1 04:00 05/13/2013 05/13/2013
1 03:00 05/15/2013 05/15/2013
This is basically an unpivot query. Because of the time fields, this version chooses to do it explicitly (using cross join
and case
) rather than using unpivot
:
select t.*
from (select h.empid,
(case when n = 0 then Monday
when n = 1 then Tuesday
when n = 2 then Wednesday
when n = 3 then Thursday
when n = 4 then Friday
when n = 5 then Saturday
when n = 6 then Sunday
end) as hours,
(startdate + n) as StartDate,
(startdate + n) as EndDate
from hours h join
(select 0 as n union all
select 1 union all
select 2 union all
select 3 union all
select 4 union all
select 5 union all
select 6
) n
) t
where hours > 0;
You can see the SQLFiddle here . And there is no problem running this on larger amounts of data.
This should get you started:
declare @Hours as Table ( EmpId Int, Monday Time, Tuesday Time, Wednesday Time,
Thursday Time, Friday Time, Saturday Time, Sunday Time, StartDate Date, EndDate Date );
insert into @Hours
( EmpId, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, StartDate, EndDate )
values
( 1, '08:00', '08:12', '00:00', '04:00', '00:00', '03:00', '00:00', '20130510', '20130516' );
select * from @Hours;
with Week as (
-- Build a table of all of the dates in the work week.
select StartDate as WorkDate, EndDate
from @Hours
union all
select DateAdd( day, 1, WorkDate ), EndDate
from Week
where WorkDate < EndDate )
-- Output the result.
select EmpId,
case DatePart( weekday, W.WorkDate )
when 1 then H.Monday
when 2 then H.Tuesday
when 3 then H.Wednesday
when 4 then H.Thursday
when 5 then H.Friday
when 6 then H.Saturday
when 7 then H.Sunday
end as Hours,
WorkDate as StartDate, WorkDate as EndDate,
DatePart( weekday, W.WorkDate ) as DayOfWeek
from Week as W inner join
@Hours as H on H.StartDate <= W.WorkDate and W.WorkDate <= H.EndDate;
with Week as (
-- Build a table of all of the dates in the work week.
select StartDate as WorkDate, EndDate
from @Hours
union all
select DateAdd( day, 1, WorkDate ), EndDate
from Week
where WorkDate < EndDate ),
DaysHours as (
-- Build a table of the hours assigned to each date.
select EmpId,
case DatePart( weekday, W.WorkDate )
when 1 then H.Monday
when 2 then H.Tuesday
when 3 then H.Wednesday
when 4 then H.Thursday
when 5 then H.Friday
when 6 then H.Saturday
when 7 then H.Sunday
end as Hours,
WorkDate as StartDate, WorkDate as EndDate
from Week as W inner join
@Hours as H on H.StartDate <= W.WorkDate and W.WorkDate <= H.EndDate )
-- Output the non-zero hours.
select EmpId, Hours, StartDate, EndDate
from DaysHours
where Hours <> Cast( '00:00' as Time );
This works for a single row, but you will need to make some changes if your dataset grows.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.