t-sql 从平面日期列表中总结日期范围,按其他列分组

Posted

技术标签:

【中文标题】t-sql 从平面日期列表中总结日期范围,按其他列分组【英文标题】:t-sql to summarize range of dates from flat list of dates, grouped by other columns 【发布时间】:2020-11-19 06:24:11 【问题描述】:

假设我有下表:

UserId   AttributeId   DateStart
1        3             1/1/2020
1        4             1/9/2020
1        3             2/2/2020
2        3             3/5/2020
2        3             4/1/2020
2        3             5/1/2020

对于每个唯一的 UserId/AttributeId 对,假定 DateEnd 是该对的下一个 DateStart 的前一天,否则它为 null(或某些默认值,如疯狂的未来 - 3000 年 12 月 31 日) .

将此操作应用于上表将产生:

UserId   AttributeId   DateStart     DateEnd
1        3             1/1/2020      2/1/2020
1        4             1/9/2020      <null>
1        3             2/2/2020      <null>
2        3             3/5/2020      3/31/2020
2        3             4/1/2020      4/30/2020
2        3             5/1/2020      <null>

在 SQL Server 2008 R2 中执行的什么 T-SQL 可以完成此任务?

【问题讨论】:

您为什么使用不受支持的 SQL Server 版本? 【参考方案1】:

我已更改查询)

请试试这个:

  SELECT 
  UserId,AttributeId,DateStart,Min(DateEnd)DateEnd
  FROM
  (
 
   SELECT X.UserId,X.AttributeId,X.DateStart, DATEADD(DD,-1,Y.DateStart) DateEnd
   FROM TAB X LEFT JOIN TAB Y
   ON (X.UserId=Y.UserId) AND (X.AttributeId=Y.AttributeId)
   AND   (X.DateStart<Y.DateStart) 

  )
 T
 GROUP BY UserId,AttributeId,DateStart
 ORDER BY DateStart

【讨论】:

非常感谢您发布答案!如果相同的 UserId/AttributeId 组合在表中有 3 个或更多条目,我认为这将不起作用。我修改了我的问题以显示一个示例 - 请查看最后一行是新的。 我已更改查询)请检查一下 SFun28,告诉我,你试试查询吗?))【参考方案2】:

你在描述lead()

select t.*,
       dateadd(day, -1, lead(dateStart) over (partition by userId, attributeId order by dateStart)) as dateEnd
from t;

【讨论】:

对不起...应该说明我需要这个才能在 SQL 2008 R2 中工作!

以上是关于t-sql 从平面日期列表中总结日期范围,按其他列分组的主要内容,如果未能解决你的问题,请参考以下文章

SSIS - 如何从平面文件插入到具有日期范围的OLE DB?

如何识别 T-SQL 中每个不同成员的多个开始和结束日期范围中的第一个间隙

C# - 创建平面列表的树结构(按日期)

Pandas groupby 多列基础日期列按纪元周

如何从 SQL (T-SQL) 中的日期组件创建日期?

按日期范围删除数据框中的行。