【问题标题】:SQL Dynamic Start-time Window GroupingSQL 动态开始时间窗口分组
【发布时间】:2020-03-31 20:37:06
【问题描述】:

在给定“日期”列的情况下,我希望编写一个 SQL 查询以返回下面的“window_group”列:

这个window_group列是这样生成的..

  • 每个窗口在窗口内的第一个日期后window_length 天结束
  • 新窗口从最后一个窗口结束后的第一个日期开始
| date      | window_group |
|-----------|--------------|
| 1/1/2020  |     a        |
| 1/2/2020  |     a        |
| 1/5/2020  |     b        |
| 1/7/2020  |     b        |
| 1/12/2020 |     c        |
| 1/13/2020 |     c        |

预期的 sql 输出如上所示,窗口长度为 3。

这张图也可以帮助你理解:

1  2        5     7             12 13 
|  |        |     |              |  |     
+--+--+--+--+--+--+--+--+--+--+--+--+--+--...
1  2  3  4  5  6  7  8  9  10 11 12 13 14
a  a  a  .  b  b  b  .  .  .  .  c  c  c


window_length: 3

groupings:
a: [1, 2]
b: [5, 7]
c: [12, 13]

我尝试使用窗口函数和延迟来实现此功能,以确定上一条记录的分配组中第一行的日期,但这不起作用,因为在分配时我无法访问更新的分配组.

任何帮助将不胜感激!

【问题讨论】:

  • 您的表格数据似乎与给出的示例不相关。
  • 谢谢@alexherm,我更新了示例。

标签: sql sql-server window-functions


【解决方案1】:

这是一个棘手的逻辑。为此,您需要一个递归 CTE:

with t as (
      select t.*, row_number() over (order by date) as seqnum
      from <table> t
     ),
     cte as (
      select t.date, dateadd(day, 3, t.date) as grpend, 1 as grp, t.seqnum
      from t
      where seqnum = 1
      union all
      select t.date,
             (case when t.date <= cte.grpend then cte.grpend else dateadd(day, 3, t.date) end),
             (case when t.date <= cte.grpend then cte.grp else cte.grp + 1 end),
             t.seqnum
      from cte join
           t
           on t.seqnum = cte.seqnum + 1
     )
select *
from cte;

【讨论】:

  • 谢谢你的回答戈登!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-30
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
相关资源
最近更新 更多