需要像这种格式的Sql查询输出

时间:2013-06-12 01:28:16

标签: sql sql-server-2008

我有一张时间表单,当我获取它将会显示这样的记录一周时。

此记录是从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

2 个答案:

答案 0 :(得分:1)

这基本上是一个univot查询。由于时间字段,此版本选择明确(使用cross joincase)而不是使用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 here。在大量数据上运行此功能没有问题。

答案 1 :(得分: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 );

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