sql-server - SQL Server - 将每天的记录转换为日期范围(有间隙)

标签 sql-server tsql

我找到了很多关于如何将日期范围转换为每天记录的问题和答案,但我需要相反的东西,但还找不到任何东西。

假设我有这个数据集:

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/

相关文章:

sql-server - 引用代理键

sql-server - SQL 数据比较 - 某些表丢失

mysql - 索引 SQL 数据库

tsql - 从 SSRS 中的 ExecutionLog 中分割参数(字符串函数)

sql-server - 确定 T-SQL 中 SP 参数是否具有默认值

sql - 如何在sql server中进行交易技术分析计算?

sql - 如何在没有 key 的情况下删除插入的记录?

SQL字符串添加问题

c# - 确定是否从模式生成 ExecuteNonQuery 或 ExecuteReader

sql - 循环通过 xml 然后更新 SQL 中的 xml 变量