我找到了很多关于如何将日期范围转换为每天记录的问题和答案,但我需要相反的东西,但还找不到任何东西。
假设我有这个数据集:
User | Available
1 | 01-01-2019
1 | 02-01-2019
1 | 03-01-2019
1 | 04-01-2019
2 | 05-01-2019
2 | 06-01-2019
2 | 07-01-2019
2 | 10-01-2019
2 | 11-01-2019
2 | 12-01-2019
所以我们有用户 1,他在 01/01/2019 到 04/01/2019 期间有空。然后我们有用户 2,他在 05/01/2019 到 07/01/2019 和 10/01/2019 到 12/01/2019 之间可用。
我正在寻找的结果应该是这样的:
User | Start | End
1 | 01-01-2019 | 04-01-2019
2 | 05-01-2019 | 07-01-2019
2 | 10-01-2019 | 12-01-2019
用户 1 使用最小/最大日期计算起来相当容易,但是由于用户 2 的间隔,我完全迷路了。有什么建议吗?
最佳答案
我之前也曾在某个地方这样做过,这是我使用的解决方案。基本上使用按分组列拆分并按日期排序的行号,并另外计算从特定日期开始的天数(任何硬编码的日期都可以)。
这里的关键是,当行数增加 1 时,如果天数是连续的,anchor 差异只会增加 1 和 1。因此, anchor 差异和行号之间的其余部分将保持不变仅当存在连续日期时,允许您分组并计算最小值/最大值。
IF OBJECT_ID('tempdb..#Availabilities') IS NOT NULL
DROP TABLE #Availabilities
CREATE TABLE #Availabilities (
[User] INT,
Available DATE)
INSERT INTO #Availabilities
VALUES
(1, '2019-01-01'),
(1, '2019-01-02'),
(1, '2019-01-03'),
(1, '2019-01-04'),
(2, '2019-01-05'),
(2, '2019-01-06'),
(2, '2019-01-07'),
(2, '2019-01-10'),
(2, '2019-01-11'),
(2, '2019-01-12')
;WITH WindowFunctions AS
(
SELECT
A.[User],
A.Available,
AnchorDayDifference = DATEDIFF(DAY, '2018-01-01', A.Available),
RowNumber = ROW_NUMBER() OVER (PARTITION BY A.[User] ORDER BY A.Available)
FROM
#Availabilities AS A
)
SELECT
T.[User],
Start = MIN(T.Available),
[End] = MAX(T.Available)
FROM
WindowFunctions AS T
GROUP BY
T.[User],
T.AnchorDayDifference - T.RowNumber
结果:
User Start End
1 2019-01-01 2019-01-04
2 2019-01-05 2019-01-07
2 2019-01-10 2019-01-12
WindowFunctions
值是(添加了后验剩余结果):
User Available AnchorDayDifference RowNumber GroupingRestResult
1 2019-01-01 365 1 364
1 2019-01-02 366 2 364
1 2019-01-03 367 3 364
1 2019-01-04 368 4 364
2 2019-01-05 369 1 368
2 2019-01-06 370 2 368
2 2019-01-07 371 3 368
2 2019-01-10 374 4 370
2 2019-01-11 375 5 370
2 2019-01-12 376 6 370
关于sql-server - SQL Server - 将每天的记录转换为日期范围(有间隙),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54184958/