简体   繁体   中英

Need Sql query output like this format

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM