【发布时间】:2021-03-26 09:28:41
【问题描述】:
我正在尝试确定在指定日期之前和之后具有连续日期的记录数(上一条记录的结束日期与下一条记录的开始日期相同),并在出现时立即忽略任何连续记录链条断裂。
如果我有以下数据:
-- declare vars
DECLARE @dateToCheck date = '2020-09-20'
DECLARE @numRecsBefore int = 0
DECLARE @numRecsAfter int = 0
DECLARE @tempID int
-- temp table
CREATE TABLE #dates
(
[idx] INT IDENTITY(1,1),
[startDate] DATETIME ,
[endDate] DATETIME,
[prevEndDate] DATETIME
)
-- insert temp table
INSERT INTO #dates
( [startDate], [endDate] )
VALUES ( '2020-09-01', '2020-09-04' ),
( '2020-09-04', '2020-09-10' ),
( '2020-09-10', '2020-09-16' ),
( '2020-09-17', '2020-09-19' ),
( '2020-09-19', '2020-09-20' ),
--
( '2020-09-20', '2020-09-23' ),
( '2020-09-25', '2020-09-26' ),
( '2020-09-27', '2020-09-28' ),
( '2020-09-28', '2020-09-30' ),
( '2020-10-01', '2020-09-05' )
-- update with previous records endDate
DECLARE @maxRows int = (SELECT MAX(idx) FROM #dates)
DECLARE @intCount int = 0
WHILE @intCount <= @maxRows
BEGIN
UPDATE #dates SET prevEndDate = (SELECT endDate FROM #dates WHERE idx = (@intCount - 1) ) WHERE idx=@intCount
SET @intCount = @intCount + 1
END
-- clear any breaks in the chain?
-- number of consecutive records before this date
SET @numRecsBefore = (SELECT COUNT(idx) FROM #dates WHERE startDate = prevEndDate AND endDate <= @dateToCheck)
-- number of consecutive records after this date
SET @numRecsAfter = (SELECT COUNT(idx) FROM #dates WHERE startDate = prevEndDate AND endDate >= @dateToCheck)
-- return & clean up
SELECT * FROM #dates
SELECT @numRecsBefore AS numBefore, @numRecsAfter AS numAfter
DROP TABLE #dates
由于指定日期为 '2020-09-20,我希望 @numRecsBefore = 2 和 @numRecsAfter = 1。这不是我得到的,因为它会计算所有连续记录。
必须有更好的方法来做到这一点。我知道循环不是最佳的,但我无法让 LAG() 或 LEAD() 工作。我整个上午都在尝试不同的方法和搜索,但我发现的所有内容都没有处理两个日期,或者链中的中断。
【问题讨论】:
标签: sql sql-server datetime sql-server-2012 gaps-and-islands