用于聚合窗口的 sql

Posted

技术标签:

【中文标题】用于聚合窗口的 sql【英文标题】:sql for aggregating a window 【发布时间】:2018-01-03 21:25:55 【问题描述】:

我需要聚合一个窗口(在 PostgreSQL 中):

我有这张表“locationtimestamp”:

seq | location     | timestamp
-------------------------------------
1   | home         | 2018-01-02 18:00
2   | home         | 2018-01-03 08:00
3   | work         | 2018-01-03 09:00
4   | work         | 2018-01-03 16:00
5   | home         | 2018-01-03 17:00
6   | elsewhere    | 2018-01-03 18:00
7   | elsewhere    | 2018-01-03 20:00
8   | home         | 2018-01-03 21:00
9   | home         | 2018-01-03 22:00
10  | home         | 2018-01-03 23:00

我想要这个结果:

location  | min_seq | max_seq | min_timestamp    | max_timestamp
-------------------------------------------------------------------
home      | 1       | 2       | 2018-01-02 18:00 | 2018-01-03 08:00
work      | 3       | 4       | 2018-01-03 09:00 | 2018-01-03 16:00
home      | 5       | 5       | 2018-01-03 17:00 | 2018-01-03 17:00
elsewhere | 6       | 7       | 2018-01-03 18:00 | 2018-01-03 20:00
home      | 8       | 10      | 2018-01-03 21:00 | 2018-01-03 23:00

我尝试使用窗口函数来实现这一点,但结果是 10 行(表中的行数)而不是所需的聚合 5。

到目前为止我的尝试(不工作):

SELECT
   location,
   MIN(seq) OVER w min_seq,
   MAX(seq) OVER w max_seq,
   MIN("timestamp") OVER w min_timestamp,
   MAX("timestamp") OVER w max_timestamp
FROM locationtimestamp
WINDOW w AS (PARTITION BY location ORDER BY seq ASC)
ORDER BY seq

【问题讨论】:

dbfiddle.uk/… @RadimBača 谢谢!请参阅我对 Gordon Linoff 回答的评论。这是唯一的方法吗?或者所有的差距和孤岛问题都以类似的方式解决了吗? ;-) 我相信您也可以使用其他窗口函数,例如laglead,但是,这是我见过的最优雅的解决方案。 【参考方案1】:

一种方法是行号不同:

select location, min(seq), max(seq), min(timestamp), max(timestamp)
from (select l.*,
             row_number() over (order by timestamp) as seqnum,
             row_number() over (partition by location order by timestamp) as seqnum_l
      from locationtimestamp l
     ) l
group by location, (seqnum - seqnum_l);

那是作品一开始是相当神秘的。盯着子查询的结果,以便更好地理解。

【讨论】:

谢谢戈登!这是一个解决方案;-) 但是“摆弄”行号是在窗口一侧聚合行的唯一方法吗?我希望有一种更具描述性/功能性的方式来做到这一点......? @frankhommers 。 . .还有其他方法,但在您的情况下这是最简单的。

以上是关于用于聚合窗口的 sql的主要内容,如果未能解决你的问题,请参考以下文章

Flink SQL --- 窗口聚合

Spark SQL:与时间窗口聚合

Pyspark SQL/SQL 中的窗口和聚合函数

重学SQL窗口函数

查找 SQL 聚合函数调用中的百分比可能没有嵌套聚合或窗口函数

sql中的 开窗函数over() 聚合函数 排名函数