繁体   English   中英

按小时拆分日期/时间数据并将日期/时间范围扩展为行

[英]Split Date/Time Data by Hour and Expand a Range of Date/Time into Rows

我正在尝试使用 SQL Server 将一系列日期/时间数据扩展为多行。 例如,我的数据看起来像

Date           StartTime    EndTime     EmployeeID     ShiftType
10/1/2019     8:30:00AM    4:57:00PM     52148          Shift
10/2/2019     9:00:00AM    5:24:00PM     72156          Shift
10/2/2019     8:27:00AM    4:40:00PM     59232          Shift

我想按小时将日期和时间范围扩展为多行。 它看起来像:

Date           StartTime    EndTime     EmployeeID     ShiftType
10/1/2019     8:30:00AM    9:00:00PM     52148          Shift
10/1/2019     9:00:00AM    10:00:00PM     52148          Shift
10/1/2019     10:00:00AM   11:00:00PM     52148          Shift
10/1/2019     11:00:00AM   12:00:00PM     52148          Shift
10/1/2019     12:00:00AM   1:00:00PM     52148          Shift
10/1/2019     1:00:00AM    2:00:00PM     52148          Shift
10/1/2019     2:00:00AM    3:00:00PM     52148          Shift
10/1/2019     3:00:00AM    4:00:00PM     52148          Shift
10/1/2019     4:30:00AM    4:57:00PM     52148          Shift
10/2/2019     9:00:00AM    10:00:00PM     72156          Shift
10/2/2019     10:00:00AM   11:00:00PM     72156          Shift
                  .......

如果开始时间是 8:20,我想在前 40 分钟单独排成一行,所以它可能是 8:20 -9:00 然后是 9:00-10:同样的事情适用于结束时间。 我厌倦了这样的事情,但显然它不起作用,因为我想以小时为单位拆分它们。

Declare @StartDate DATETIME = '2016-09-26 00:00:00.000';

With SampleDateTable AS 
  (
    SELECT @StartDate AS myDate
    UNION ALL
    SELECT DATEADD(Day,1,myDate)
    FROM Sheet1$
    WHERE DATEADD(Day,1,myDate) <=  GETDATE()
)
SELECT 
    EmployeeID,
    a.myDate,
FROM SampleDateTable a
     INNER JOIN 
      (
        SELECT EmployeeID, MIN(StartTime) MinStartTime
        FROM Sheet1$
        GROUP BY EmployeeID
      ) EachEmployee ON 
        a.MyDate >= EachEmployee.MinStartTime
     LEFT JOIN 
    Sheet1$ S ON
        EachEmployee.EmployeeID = S.EmployeeID AND
        a.myDate >= S.StartDate AND
        a.myDate <= ISNULL(S.EndDate, GETDATE())
ORDER BY EachEmployee.EmployeeID DESC, a.MyDate
OPTION (MAXRECURSION 0)

我很感激这方面的任何帮助。 谢谢。

这是使用临时计数表的一种选择

例子

Declare @YourTable Table ([Date] date,[StartTime] time,[EndTime] time,[EmployeeID] int,[ShiftType] varchar(50))  
Insert Into @YourTable Values 
 ('10/1/2019','8:30:00AM','4:57:00PM',52148,'Shift')
,('10/2/2019','9:00:00AM','5:24:00PM',72156,'Shift')
,('10/2/2019','8:27:00AM','4:40:00PM',59232,'Shift')
 
Select Date
      ,StartTime = case when N=datepart(hour,StartTime) then StartTime else TimeFromParts(N,0,0,0,0) end
      ,EndTime   = case when N=datepart(hour,EndTime)   then EndTime   else TimeFromParts(N+1,0,0,0,0) end
      ,EmployeeID
      ,ShiftType
 From  @YourTable A
 Join ( values (0),(1),(2),(3),(4),(5),(6)
              ,(7),(8),(9),(10),(11),(12),(13)
              ,(14),(15),(16),(17),(18),(19),(20)
              ,(21),(22),(23)
       ) B(N)
  on  N between datepart(hour,StartTime) and datepart(hour,EndTime)

退货

Date        StartTime           EndTime             EmployeeID  ShiftType
2019-10-01  08:30:00.0000000    09:00:00.0000000    52148   Shift
2019-10-01  09:00:00.0000000    10:00:00.0000000    52148   Shift
2019-10-01  10:00:00.0000000    11:00:00.0000000    52148   Shift
2019-10-01  11:00:00.0000000    12:00:00.0000000    52148   Shift
2019-10-01  12:00:00.0000000    13:00:00.0000000    52148   Shift
2019-10-01  13:00:00.0000000    14:00:00.0000000    52148   Shift
2019-10-01  14:00:00.0000000    15:00:00.0000000    52148   Shift
2019-10-01  15:00:00.0000000    16:00:00.0000000    52148   Shift
2019-10-01  16:00:00.0000000    16:57:00.0000000    52148   Shift
2019-10-02  09:00:00.0000000    10:00:00.0000000    72156   Shift
2019-10-02  10:00:00.0000000    11:00:00.0000000    72156   Shift
2019-10-02  11:00:00.0000000    12:00:00.0000000    72156   Shift
2019-10-02  12:00:00.0000000    13:00:00.0000000    72156   Shift
2019-10-02  13:00:00.0000000    14:00:00.0000000    72156   Shift
2019-10-02  14:00:00.0000000    15:00:00.0000000    72156   Shift
2019-10-02  15:00:00.0000000    16:00:00.0000000    72156   Shift
2019-10-02  16:00:00.0000000    17:00:00.0000000    72156   Shift
2019-10-02  17:00:00.0000000    17:24:00.0000000    72156   Shift
2019-10-02  08:27:00.0000000    09:00:00.0000000    59232   Shift
2019-10-02  09:00:00.0000000    10:00:00.0000000    59232   Shift
2019-10-02  10:00:00.0000000    11:00:00.0000000    59232   Shift
2019-10-02  11:00:00.0000000    12:00:00.0000000    59232   Shift
2019-10-02  12:00:00.0000000    13:00:00.0000000    59232   Shift
2019-10-02  13:00:00.0000000    14:00:00.0000000    59232   Shift
2019-10-02  14:00:00.0000000    15:00:00.0000000    59232   Shift
2019-10-02  15:00:00.0000000    16:00:00.0000000    59232   Shift
2019-10-02  16:00:00.0000000    16:40:00.0000000    59232   Shift

对于递归查询,您应该从示例数据开始,然后从那里调整它。

在递归查询中,我们添加了一个额外的列:下一小时边界,又名NextTime 例如,对于StartTime 8:27,下一小时的边界是 9:00。 递归时,我们将其用作下一个StartTime ,然后EndTime ,直到到达EndTime

在结果查询中,我们隐藏NextTime列,但选择NextTimeEndTime较早的作为该结果行的EndTime 由于递归不能以良好的顺序提供数据,我们还需要按StartTime排序。

WITH hourly AS (
  SELECT Date, EmployeeID, ShiftType, EndTime, StartTime
       , TIMEFROMPARTS(DATEPART(hh, StartTime) + 1,
                       0, 0, 0, 0 ) AS NextTime
    FROM SampleDateTable
  UNION ALL
  SELECT Date, EmployeeID, ShiftType, EndTime, NextTime
       , TIMEFROMPARTS(DATEPART(hh, NextTime) + 1,
                       0, 0, 0, 0 ) AS NextTime
    FROM hourly
   WHERE NextTime < EndTime
)
SELECT Date, StartTime
     , CASE WHEN NextTime < EndTime THEN NextTime ELSE EndTime END AS EndTime
     , EmployeeID, ShiftType
  FROM hourly
ORDER BY Date, EmployeeID DESC, StartTime

有关工作示例,请参阅SQL Fiddle

架构

CREATE TABLE SampleDateTable (
  Date        date        NOT NULL,
  StartTime   time(0)     NOT NULL,
  EndTime     time(0)     NOT NULL,
  EmployeeID  int         NOT NULL,
  ShiftType   varchar(10) NOT NULL
);

INSERT INTO SampleDateTable VALUES
( '10/1/2019', '8:30:00AM', '4:57:00PM', 52148, 'Shift' ),
( '10/2/2019', '9:00:00AM', '5:24:00PM', 72156, 'Shift' ),
( '10/2/2019', '8:27:00AM', '4:40:00PM', 59232, 'Shift' );

输出

Date        StartTime  EndTime   EmployeeID  ShiftType
2019-10-01  08:30:00   09:00:00  52148       Shift
2019-10-01  09:00:00   10:00:00  52148       Shift
2019-10-01  10:00:00   11:00:00  52148       Shift
2019-10-01  11:00:00   12:00:00  52148       Shift
2019-10-01  12:00:00   13:00:00  52148       Shift
2019-10-01  13:00:00   14:00:00  52148       Shift
2019-10-01  14:00:00   15:00:00  52148       Shift
2019-10-01  15:00:00   16:00:00  52148       Shift
2019-10-01  16:00:00   16:57:00  52148       Shift
2019-10-02  09:00:00   10:00:00  72156       Shift
2019-10-02  10:00:00   11:00:00  72156       Shift
2019-10-02  11:00:00   12:00:00  72156       Shift
2019-10-02  12:00:00   13:00:00  72156       Shift
2019-10-02  13:00:00   14:00:00  72156       Shift
2019-10-02  14:00:00   15:00:00  72156       Shift
2019-10-02  15:00:00   16:00:00  72156       Shift
2019-10-02  16:00:00   17:00:00  72156       Shift
2019-10-02  17:00:00   17:24:00  72156       Shift
2019-10-02  08:27:00   09:00:00  59232       Shift
2019-10-02  09:00:00   10:00:00  59232       Shift
2019-10-02  10:00:00   11:00:00  59232       Shift
2019-10-02  11:00:00   12:00:00  59232       Shift
2019-10-02  12:00:00   13:00:00  59232       Shift
2019-10-02  13:00:00   14:00:00  59232       Shift
2019-10-02  14:00:00   15:00:00  59232       Shift
2019-10-02  15:00:00   16:00:00  59232       Shift
2019-10-02  16:00:00   16:40:00  59232       Shift

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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