按键列出的SQL循环开始和结束日期

按键列出的SQL循环开始和结束日期,sql,sql-server-2016,Sql,Sql Server 2016,(SQL Server 2016)给定了如下所述的密钥和日期范围: Key Date a 1/1/2018 b 1/1/2018 a 1/2/2018 b 1/2/2018 a 1/3/2018 b 1/3/2018 a 1/4/2018 b 1/4/2018 a 1/5/2018 b 1/5/2018 a 1/13/2018 b 1/13/2018 a 1/1

(SQL Server 2016)给定了如下所述的密钥和日期范围:

Key Date a 1/1/2018 b 1/1/2018 a 1/2/2018 b 1/2/2018 a 1/3/2018 b 1/3/2018 a 1/4/2018 b 1/4/2018 a 1/5/2018 b 1/5/2018 a 1/13/2018 b 1/13/2018 a 1/14/2018 b 1/14/2018 a 1/15/2018 b 1/15/2018 a 1/16/2018 a 1/17/2018 etc. 关键日期 a 2018年1月1日 b 2018年1月1日 a 2018年1月2日 b 2018年1月2日 a 2018年1月3日 b 2018年1月3日 a 2018年1月4日 b 2018年1月4日 a 2018年1月5日 b 2018年1月5日 a 2018年1月13日 b 2018年1月13日 a 2018年1月14日 b 2018年1月14日 a 2018年1月15日 b 2018年1月15日 a 2018年1月16日 a 2018年1月17日 等 是否可以返回以下内容(每个键的组始终相隔一天):

键开始日期结束日期 a 2018年1月1日2018年5月1日(a的第一组) a 2018年1月13日2018年1月17日(a的第二组) b 2018年1月1日2018年5月1日 b 2018年1月13日2018年1月15日 a*新开始**新结束* 等
编辑:谢谢你的评论。为了回答下面的问题,我尝试了Lead()、游标和多个嵌入循环。在大多数情况下,结果集不正确(日期错误或跳过键),或者执行时间过长。

这是一种间隙和孤岛问题,但它与标准问题略有不同,因为两个键的日期序列彼此独立。您可以使用一个
行号()来执行此操作
与日期的差异:

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标准语法进行日期运算;所有数据库都支持该功能,但语法可能会有所不同。

您尝试过什么?什么;您的数据库管理系统是什么?这看起来像是一个缺口和孤岛问题。你用哪一种?“SQL”只是一种查询语言,而不是特定数据库产品的名称。请为您正在使用的数据库产品添加标签,
postgresql
oracle
db2
sql server
,…感谢您的回复。您描述的结果集确实返回了每个键的边界日期,例如“a”2018年1月1日2017年1月1日,但如何返回子组“a”2018年1月1日2018年1月5日和“a”2018年1月13日1月17日/2018@Semp . . . 第二种解决方案更适合您的问题。Stackoverflow是一个新手,我从阅读一些帖子中了解到“谢谢”是不必要的,但您的解决方案为我节省了无数个小时,甚至数天的沮丧。非常感谢。
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);