Dan*_*ell 5 sql sql-server gaps-and-islands
请帮帮我,我有一个奇怪的SQL问题.
因此,如果您假设标准办公时间在9:00到17:00之间.
我有一个休息列表,我想将这些休息时间添加到我的工作日,并在我可用时返回一系列休息时间.
这个SQL显示了我的工作时间,休息时间以及我希望输出的内容:
DECLARE @WorkingHours TABLE
(StartTime TIME, EndTime TIME, EventDate date, IsBreak bit)
insert @WorkingHours select '09:00', '17:00', '2018-08-15', 0;
DECLARE @Breaks TABLE
(StartTime TIME, EndTime TIME, EventDate date, IsBreak bit)
insert @Breaks select '11:30', '12:30', '2018-08-15', 1;
insert @Breaks select '12:00', '13:00', '2018-08-15', 1;
insert @Breaks select '15:00', '16:00', '2018-08-15', 1;
insert @Breaks select '15:25', '15:55', '2018-08-15', 1;
insert @Breaks select '09:50', '10:05', '2018-08-15', 1;
insert @Breaks select '15:50', '16:05', '2018-08-15', 1;
DECLARE @Output TABLE
(StartTime TIME, EndTime TIME, EventDate date)
insert @Output select '09:00', '09:50', '2018-08-15';
insert @Output select '10:05', '11:30', '2018-08-15';
insert @Output select '13:00', '15:00', '2018-08-15';
insert @Output select '16:05', '17:00', '2018-08-15';
SELECT * FROM @Output
Run Code Online (Sandbox Code Playgroud)
这是我设法来的最接近的,但它不处理重叠中断或休息时间的中断.
DECLARE @Final TABLE
(StartTime TIME, EndTime TIME, EventDate date, IsBreak bit)
INSERT INTO @Final
SELECT * FROM @WorkingHours
UNION
SELECT * FROM @Breaks
SELECT CASE WHEN t1.IsBreak = 0 THEN t1.StartTime
ELSE t1.EndTime
END AS StartTime ,
CASE WHEN LEAD(t1.EventDate) OVER
( ORDER BY t1.EventDate,
t1.[StartTime]
) = t1.EventDate THEN
coalesce(Lead(t1.StartTime) OVER
( ORDER BY t1.EventDate,
t1.[StartTime]),
'17:00'
)
ELSE '17:00'
END AS EndTime,
t1.EventDate
FROM @Final t1
INNER
JOIN @Final t2
ON t1.EventDate = t2.EventDate
AND t2.IsBreak = 0
Run Code Online (Sandbox Code Playgroud)
任何人都可以提供的任何帮助将不胜感激.
可以通过使用 过滤最后一个查询的结果来获得所需的输出StartTime < EndTime,例如使用 cte :
WITH cte AS ( SELECT CASE
WHEN t1.IsBreak = 0 THEN t1.StartTime
ELSE t1.EndTime
END AS StartTime
, CASE WHEN LEAD(t1.EventDate) OVER ( ORDER BY t1.EventDate, t1.[StartTime]) = t1.EventDate
THEN COALESCE(LEAD(t1.StartTime) OVER( ORDER BY t1.EventDate, t1.[StartTime]), '17:00')
ELSE
'17:00'
-- (
-- SELECT MAX(EndTime)
-- FROM @Final
-- WHERE IsBreak = 0
-- AND [@Final].EventDate = t1.EventDate
-- )
END AS EndTime
, t1.EventDate
FROM @Final t1
INNER JOIN @Final t2
ON t1.EventDate = t2.EventDate
AND t2.IsBreak = 0 )
SELECT *
FROM cte
WHERE StartTime < EndTime
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |