答案 0 :(得分:0)
如果仅依靠基于集合的逻辑和Windows函数(行号等),这是困难的,因为您需要不断查看下一行以确定日期是否为在当前的1天内。
直觉是您将需要游标或while循环逻辑。
一个“快速”解决方案是对数据运行预解析脚本,以得出“匹配组”值。
一旦有了匹配的组值,就可以轻松使用Windows函数。
类似的事情(最有可能采用其他/更好的方法得出匹配组)。
我还添加了RowId INT作为主键,以便您可以使用+或-逻辑(前进/后退)轻松地自我加入。
基本上,当下一个日期位于当前日期的0到1天之间时,循环遍历添加匹配组INT的数据。
DECLARE
@TestData TABLE
(
[Id] UNIQUEIDENTIFIER,
[Date] DATETIME,
RowId INT IDENTITY (1, 1) PRIMARY KEY,
MatchGroupKey INT
);
INSERT INTO @TestData
(
Id,
[Date]
)
VALUES
(
NEWID(), '20190504'
),
(
NEWID(), '20190513'
),
(
NEWID(), '20190515'
),
(
NEWID(), '20190516'
),
(
NEWID(), '20190517'
),
(
NEWID(), '20190521'
),
(
NEWID(), '20190522'
),
(
NEWID(), '20190523'
),
(
NEWID(), '20190524'
),
(
NEWID(), '20190526'
),
(
NEWID(), '20190527'
);
-- Derive a "match group" key
DECLARE
@LoopCounter INT = 1,
@TotalRows INT =
(
SELECT
COUNT(*)
FROM
@TestData
);
DECLARE
@CurrentID UNIQUEIDENTIFIER,
@CurrentDate DATETIME,
@CurrentRowId INT,
@NextID UNIQUEIDENTIFIER,
@NextDate DATETIME,
@NextRowId INT,
@MatchGroupKey INT = 1;
WHILE (@LoopCounter <= @TotalRows)
BEGIN
-- Get current row
SELECT
@CurrentID = Id,
@CurrentDate = [Date],
@CurrentRowId = RowId
FROM
@TestData
WHERE
RowId = @LoopCounter;
--Get next row
SELECT
@NextID = Id,
@NextDate = [Date],
@NextRowId = RowId
FROM
@TestData
WHERE
RowId = @LoopCounter + 1;
IF DATEDIFF(dd, @CurrentDate, @NextDate) BETWEEN 0 AND 1
BEGIN
--If next row is same or within 1 day then update current/previous with match group
UPDATE
t1
SET
t1.MatchGroupKey = @MatchGroupKey
FROM
@TestData t1
WHERE
t1.RowId IN (@LoopCounter, @LoopCounter + 1);
END; ELSE BEGIN
--If next row is not within the 1 day then update just the current row with match value and increment the match value for next iteration
UPDATE
t1
SET
t1.MatchGroupKey = @MatchGroupKey
FROM
@TestData t1
WHERE
t1.RowId IN (@LoopCounter);
SET @MatchGroupKey += 1;
END;
SET @LoopCounter += 1;
END;
3FEADF3A-8380-46C6-8280-314FD2F619FB 2019-05-04 00:00:00.000 1 1
C487A5B9-285C-4C4F-A2BD-D1AD6272BEC2 2019-05-13 00:00:00.000 2 2
273E41FD-B910-42AB-BF22-ECE9B13B2EDA 2019-05-15 00:00:00.000 3 3
4C5E8A74-8B2E-41D8-9F32-012EBB030631 2019-05-16 00:00:00.000 4 3
1794C36E-CAA1-430C-9BB2-CECC1A85BBCE 2019-05-17 00:00:00.000 5 3
853B8296-5040-44CF-8F1C-F3E9CF5ADC24 2019-05-21 00:00:00.000 6 4
7E7E4288-13CC-4060-BCFF-A75FB4554B1D 2019-05-22 00:00:00.000 7 4
745BEE56-C2CC-4FC8-939F-DB1F5C713015 2019-05-23 00:00:00.000 8 4
F25613A6-B7CF-4131-A697-CC3A974595FC 2019-05-24 00:00:00.000 9 4
F98A02AD-8570-4A7D-B752-A34648949498 2019-05-26 00:00:00.000 10 5
D582E2BB-7625-4E12-8A09-90D1C2E769EC 2019-05-27 00:00:00.000 11 5
所以现在您在最后一列中有一个匹配组值。
现在很容易获得结果:
SELECT
Id,
[Date],
ROW_NUMBER() OVER (PARTITION BY MatchGroupKey ORDER BY Date) rn
FROM
@TestData;
5204D618-B0D9-4186-AD18-7A7C4D4220B2 2019-05-04 00:00:00.000 1
F263AAAD-1CC3-4BDE-8E16-4DE890D0012B 2019-05-13 00:00:00.000 1
8FAD9002-3951-4E63-B012-C3C9E87D7700 2019-05-15 00:00:00.000 1
26CB938B-638D-40F4-B18D-6225EBF6F739 2019-05-16 00:00:00.000 2
472646E4-FD36-43E0-B579-F542AFA7110B 2019-05-17 00:00:00.000 3
7EB4248D-B942-423B-A756-FF9438CD80DF 2019-05-21 00:00:00.000 1
103027EC-5D5E-4BD9-99A8-44274F0BE383 2019-05-22 00:00:00.000 2
79609995-D2CE-443E-AE17-DE3D9B4B6F40 2019-05-23 00:00:00.000 3
273ADCD6-0CC8-4DB9-9627-CC6FAA87D388 2019-05-24 00:00:00.000 4
3D6E53F0-976F-4FFC-936B-9503E28DE862 2019-05-26 00:00:00.000 1
573ED4AC-F370-48E5-BE79-65A847AD6CA4 2019-05-27 00:00:00.000 2