SQL 按键重复开始和结束日期

Posted

技术标签:

【中文标题】SQL 按键重复开始和结束日期【英文标题】:SQL recurring start and end dates by key 【发布时间】:2018-06-18 21:04:42 【问题描述】:

(SQL Server 2016)给定一个键和日期范围,如下所述:

关键日期 2018 年 1 月 1 日 b 2018 年 1 月 1 日 2018 年 1 月 2 日 b 2018 年 1 月 2 日 2018 年 1 月 3 日 b 2018 年 1 月 3 日 2018 年 1 月 4 日 b 2018 年 1 月 4 日 2018 年 1 月 5 日 b 2018 年 1 月 5 日 2018 年 1 月 13 日 b 2018 年 1 月 13 日 2018 年 1 月 14 日 b 2018 年 1 月 14 日 2018 年 1 月 15 日 b 2018 年 1 月 15 日 2018 年 1 月 16 日 2018 年 1 月 17 日 等等

是否可以返回以下内容(每个键的组总是相隔一天):

关键开始日期结束日期 a 2018 年 1 月 1 日 2018 年 1 月 5 日(a 的第一组) a 2018 年 1 月 13 日 2018 年 1 月 17 日(a 的第二组) b 2018 年 1 月 1 日 2018 年 1 月 5 日 b 2018 年 1 月 13 日 2018 年 1 月 15 日 *新的开始* *新的结束* 等等

编辑:感谢您的 cmets。针对以下问题,我尝试了 Lead()、一个游标和多个嵌入式循环。在大多数情况下,结果集不正确(放错日期或跳过键)或执行时间过长。

【问题讨论】:

你试过什么?你的 dbms 是什么? 这看起来像是一个差距和孤岛问题。 sqlshack.com/data-boundaries-finding-gaps-islands-and-more 您使用的是哪个DBMS? “SQL”只是一种查询语言,而不是特定数据库产品的名称。请为您正在使用的数据库产品添加标签postgresqloracledb2sql-server、... 【参考方案1】:

这是一种间隙和孤岛问题,但它与标准问题有点不同,因为您的两个键的日期序列是相互独立的。您可以使用一个row_number() 日期差异来做到这一点:

select key, min(date), max(date)
from (select t.*,
             row_number() over (partition by key order by date) as seqnum_k
      from t
     ) t
group by key, dateadd(day,  - seqnum_k, date)
order by key, min(date);

这是使用 ANSI 标准语法进行日期算术;所有数据库都支持该功能,但语法可能会有所不同。

【讨论】:

感谢您的回复。您描述的结果集确实返回每个键的边界日期,例如'a' 1/1/2018 1/1/2017,但是如何返回子组 'a' 1/1/2018 1/5/2018 和 'a' 1/13/2018 1/17/2018 @Semp 。 . .第二种解决方案更适合您的问题。 对 *** 很陌生,我从阅读一些帖子中了解到“谢谢”不是必需的,但您的解决方案为我节省了无数小时,如果不是几天的话。谢谢!

以上是关于SQL 按键重复开始和结束日期的主要内容,如果未能解决你的问题,请参考以下文章

SQL列表在两个日期之间重复发生日期,结束日期为下一个开始日期

获取开始日期和结束日期列之间的所有日期[重复]

熊猫从日期范围列中提取开始和结束日期[重复]

基于日期开始和结束在 FullCalendar 上重复事件

返回任何一年的开始和结束[重复]

基于日期开始和结束,在FullCalendar上重复事件