sql - 在 SQL 中动态比较不同列和行中的日期

标签 sql tsql ssms

我有一组这样的数据。

数据

ID  Start_dt    End_dt
A   1/1/2010    12/31/2010
A   1/1/2011    12/31/2011
A   6/1/2012    12/31/2012
A   1/1/2014    12/31/2014
A   1/1/2016    10/31/2016
A   1/1/2018    12/31/2018
B   1/1/2016    2/29/2016
B   3/1/2016    10/31/2016
B   1/1/2017    7/31/2017
B   1/1/2019    12/31/9999
C   1/1/2017    12/31/2017
C   1/1/2017    12/31/2018
C   1/1/2019    12/31/9999

我需要创建一个查询来查看每个成员的行,将当前的 Start_dt 与之前的 End_dt 进行比较。如果差异小于一年,则将这 2 条记录视为一次连续注册并返回组合的 MIN Start_dt 和 MAX End_dt,并对每个成员的所有行重复该操作。如果差异 >=1 年,则将其视为单独注册。

想要的结果

ID  Start_dt    End_dt
A   1/1/2010    12/31/2012
A   1/1/2014    12/31/2014
A   1/1/2016    10/31/2016
A   1/1/2018    12/31/2018
B   1/1/2016    7/31/2017
B   1/1/2019    12/31/2019
C   1/1/2017    12/31/9999

这是一个创建表查询:

if OBJECT_ID ('tempdb..#test1') is not null
drop table #test1
CREATE TABLE #test1 (
    ID varchar(10),
    Start_dt datetime,
    End_dt datetime
);

INSERT INTO #test1 VALUES ('A', '1/1/2010', '12/31/2010')
,('A', '1/1/2011', '12/31/2011')
,('A', '6/1/2012', '12/31/2012')
,('A', '1/1/2014', '12/31/2014')
,('A', '1/1/2016', '10/31/2016')
,('A', '1/1/2018', '12/31/2018')

,('B', '1/1/2016', '2/29/2016')
,('B', '3/1/2016', '10/31/2016')
,('B', '1/1/2017', '7/31/2017')
,('B', '1/1/2019', '12/31/9999')

,('C', '1/1/2017', '12/31/2017')
,('C', '1/1/2017', '12/31/2018')
,('C', '1/1/2019', '12/31/2999')

我已经尝试解决这个问题好几天了,但尝试过自连接、循环,但没有找到好的解决方案。有人可以帮忙吗?

谢谢!

最佳答案

您可以使用 lag() 或累积 max() 来获取上一个结束日期。然后将其与当前开始日期进行比较。

当相差超过一年时,新的小组开始。对这些新组开始进行累加求和,得到一个分组 id。

剩下的就是聚合:

select id, min(start_dt), max(end_dt)
from (select t1.*,
             sum(case when prev_end_dt > dateadd(year, -1, start_dt) then 0 else 1 end) over
                 (partition by id order by start_dt) as grp
      from (select t1.*,
                   max(end_dt) over (partition by id
                                      order by start_dt
                                      rows between unbounded preceding and 1 preceding
                                     ) as prev_end_dt
            from test1 t1
           ) t1
     ) t1
group by id, grp
order by id, min(start_dt);

关于sql - 在 SQL 中动态比较不同列和行中的日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55247255/

相关文章:

mysql - 是否有理由不遵循这种级联 SQL 重新索引重构模式?

sql group by 排序时出现的问题

sql-server - 如何在 SQL Server Management Studio 中备份连接

sql-server - 有没有办法简化 2 个值的 NULL 比较

sql - 从表中选择行并检查 sql 中列的条件

sql-server - SQL Server 2014 Management Studio不会记住自定义颜色

php - 在 MYSQL 中指定 SUBTIME 间隔是否会阻止查询不必要地遍历整个表?

SQL - 根据最近日期更新记录

sql - 将多行中的值求和到一行中

sql - T-sql插入大量数据问题