0

当我获取记录时,我有一个时间表,它将像这样显示一周。

这个记录是从6月10日到6月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

需要这样的输出

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
4

2 回答 2

1

这基本上是一个非透视查询。由于时间字段,此版本选择显式(使用cross joinand case)而不是使用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;

您可以在此处查看 SQLFiddle 。在大量数据上运行它没有问题。

于 2013-06-12T04:46:35.707 回答
0

这应该让你开始:

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 );

这适用于单行,但如果您的数据集增长,您将需要进行一些更改。

于 2013-06-12T01:52:15.703 回答