我正在尝试使用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)
在此方面,我将不胜感激。谢谢。
答案 0 :(得分:1)
这是使用临时统计表的一种选择
示例
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
答案 1 :(得分:0)
对于递归查询,您应该从示例数据开始,然后从那里进行调整。
在递归查询中,我们添加了一个额外的列:下一个小时边界,也称为NextTime
。例如。对于StartTime
8:27,下一个小时边界是9:00。递归时,我们将其用作下一个StartTime
,然后再次进行操作,直到达到EndTime
。
在结果查询中,我们隐藏NextTime
列,但选择NextTime
和EndTime
中的较早者作为该结果行的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