在SQL Server中,我有一个停机时间列表。它列出了每个停机时间的起始值和结束值。我想得到最后的约会,但每一个都是约会的日期。
示例:
我们假设每个停机时间都在同一天。
A) begin 09:00 End 11:00
B) begin 10:00 End 12:00
C) begin 12:00 End 13:00
D) begin 15:00 End 16:00
测试用例:
1)
At - 11:00
Results: Begin A (9:00), End C (13:00)
2)
At - 11:30
Results: Begin B (10:00), End C (13:00)
3)
At - 12:00
Results: Begin B (10:00), End C (13:00)
4)
At - 12:30
Results: Begin C (10:00), End C (13:00)
如果我们只查看“结束”值。它始终是最后的日期,每个日期混合在一起。它就像把时间停留在一个时间线上一样。你把它放在检查停机时间。无论是停机时间A还是B或C ....
注意:只有SQL查询,没有功能。我更喜欢没有递归但是。
来自麦克答案:
DECLARE @Downtime AS TABLE(beginDT datetime, endDT datetime)
INSERT INTO @Downtime VALUES('09:00','11:00')
INSERT INTO @Downtime VALUES('10:00','12:00')
INSERT INTO @Downtime VALUES('12:00','13:00')
INSERT INTO @Downtime VALUES('15:00','16:00')
我想我需要递归。 搜索@DateNow需要在beginDT和endDT之间。如果每个的endDT都有另一个停机时间,我们需要递归检查。
在我的样本中,A-B-C是连续的(或同时)。所以,如果currentTime在A的乞讨和C的结尾之间,那么实际结束时间是树停机时间的结束(13:00)
9 10 11 12 13 14 15 16
|----A----|
|----B----|
|---C---|
|---D---|
|---- A and B and C ---|
答案 0 :(得分:0)
好的,基于扩展数据,您(可能)需要递归:
- 测试变量&环境
DECLARE @TimeParam AS DATETIME
DECLARE @Downtime AS TABLE(ID VARCHAR(1), beginDT datetime, endDT datetime)
INSERT INTO @Downtime VALUES('a','09:00','11:00')
INSERT INTO @Downtime VALUES('b','10:00','12:00')
INSERT INTO @Downtime VALUES('c','12:00','13:00')
INSERT INTO @Downtime VALUES('d','15:00','16:00')
INSERT INTO @Downtime VALUES('e','12:00','17:00')
INSERT INTO @Downtime VALUES('f','15:00','19:00')
INSERT INTO @Downtime VALUES('g','19:00','20:00')
INSERT INTO @Downtime VALUES('h','20:00','21:00')
INSERT INTO @Downtime VALUES('i','21:00','22:00')
INSERT INTO @Downtime VALUES('j','22:00','23:00')
SET @TimeParam ='1900-01-01 15:30:00.000'
- 查询
DECLARE @Depth as INT --(Use this to control the recursion)
SET @Depth = 4
;WITH ConsecutiveDownTimeBase (ID, beginDT, endDT,IsBase)
AS
(
SELECT ID
, beginDT
, endDT
, 1 IsBase
FROM @DownTime dt
WHERE @TimeParam BETWEEN beginDT AND endDT
UNION ALL
-- Recursive member definition
SELECT a.ID
, a.beginDT
, a.endDT
, b.IsBase+1
FROM ConsecutiveDownTimeBase AS b
INNER JOIN @Downtime a
ON b.endDT BETWEEN a.beginDT and a.endDT
AND b.IsBase<=@Depth
UNION ALL
-- Recursive member definition
SELECT c.ID
, c.beginDT
, c.endDT
, b.IsBase+1
FROM ConsecutiveDownTimeBase AS b
INNER JOIN @Downtime c
ON b.beginDT BETWEEN c.beginDT and c.endDT
AND b.IsBase<=@Depth
)
SELECT CONVERT(TIME,MIN(beginDT)) AS beginDT
, CONVERT(TIME,MAX(endDT)) AS endDT
FROM ConsecutiveDownTimeBase
结果如下:
beginDT endDT
09:00:00.0000000 23:00:00.0000000