如何对由任意表达式描述的事件进行分组/窗口日期排序?
Posted
技术标签:
【中文标题】如何对由任意表达式描述的事件进行分组/窗口日期排序?【英文标题】:How can I group / window date ordered events delineated by an arbitrary expression? 【发布时间】:2016-05-10 17:46:52 【问题描述】:我想根据日期和一些(可能是任意的)指标将一些数据组合在一起:
Date | Ind
================
2016-01-02 | 1
2016-01-03 | 5
2016-03-02 | 10
2016-03-05 | 15
2016-05-10 | 6
2016-05-11 | 2
我想将后续(按日期排序)行组合在一起,但在 Indicator >= 10
之后打破组:
Date | Ind | Group
========================
2016-01-02 | 1 | 1
2016-01-03 | 5 | 1
2016-03-02 | 10 | 1
2016-03-05 | 15 | 2
2016-05-10 | 6 | 3
2016-05-11 | 2 | 3
我确实在博客文章的末尾找到了一种很有前途的技术:“Use this Neat Window Function Trick to Calculate Time Differences in a Time Series”(最后一个小节,“额外奖励”),但查询的重要部分使用了一个关键字 (FILTER
) '似乎在 SQL Server 中不受支持(稍后快速谷歌,我不确定它在哪里支持!)。
我仍然希望使用窗口函数的技术可能是答案。我只需要一个可以添加到每一行的计数器(就像RANK
或ROW_NUMBER
一样),但只有在某些任意条件评估为true
时才会增加。有没有办法在 SQL Server 中做到这一点?
【问题讨论】:
指标是什么,如何计算? 这不是真实数据(我知道,我知道)。实际上,我正在使用LEAD()
计算后续日期之间的差距,并且我想在差距大于特定值(例如 30 天)时划分组。出于求知欲/未来灵活性的原因,我希望得到一个适用于一般情况的答案(即“指标”可以是任意真/假表达式)。
【参考方案1】:
解决办法如下:
DECLARE @t TABLE ([Date] DATETIME, Ind INT)
INSERT INTO @t
VALUES
('2016-01-02', 1),
('2016-01-03', 5),
('2016-03-02', 10),
('2016-03-05', 15),
('2016-05-10', 6),
('2016-05-11', 2)
SELECT [Date],
Ind,
1 + SUM([Group]) OVER(ORDER BY [Date]) AS [Group]
FROM
(
SELECT *,
CASE WHEN LAG(ind) OVER(ORDER BY [Date]) >= 10
THEN 1
ELSE 0
END AS [Group]
FROM @t
) t
当前一个大于10
时,只需将行标记为1
,否则标记为0
。然后运行总和将为您提供所需的结果。
【讨论】:
不应该花这么多时间来格式化我的答案。好吧,这几乎与日期差异检查相同:sqlfiddle.com/#!6/162ab/1 @JamesZ,几乎一样:) 我非常喜欢你的回答,所以我用更易于阅读的格式对其进行了编辑(至少对我而言)。希望你不要介意! 谢谢!非常简洁,比我担心的要简单得多(实际上几乎令人尴尬),甚至结合了我的示例编号系统和选择不当的列名:)【参考方案2】:将这个想法完全归功于 Giorgi,但我修改了他的答案(为了我的利益和未来的读者)。
只需更改 CASE
语句即可查看自上次记录以来是否已过去 30 天或更长时间:
DECLARE @t TABLE ([Date] DATETIME)
INSERT INTO @t
VALUES
('2016-01-02'),
('2016-01-03'),
('2016-03-02'),
('2016-03-05'),
('2016-05-10'),
('2016-05-11')
SELECT [Date],
1 + SUM([Group]) OVER(ORDER BY [Date]) AS [Group]
FROM
(
SELECT [Date],
CASE WHEN DATEADD(d, -30, [Date]) >= LAG([Date]) OVER(ORDER BY [Date])
THEN 1
ELSE 0
END AS [Group]
FROM @t
) t
【讨论】:
感谢您关注我的实际需求:为您点赞。显然,Giorgi 回答了所提出的问题,并且(如承认的那样)启发了您的回答。以上是关于如何对由任意表达式描述的事件进行分组/窗口日期排序?的主要内容,如果未能解决你的问题,请参考以下文章