【问题标题】:How to apply aggregate function only on contiguous rows?如何仅在连续行上应用聚合函数?
【发布时间】:2015-09-19 12:49:00
【问题描述】:

在 PostgreSQL 9.4 上,我试图在一些连续的行上实现我称之为“聚合函数”的东西。示例:

输入数据:

recipe  prod1   prod2   timestamp
0       5       4       2015-07-02 08:10:34.357
0       2       7       2015-07-02 08:13:45.352
0       7       0       2015-07-02 08:16:22.098
1       3       2       2015-07-02 08:22:14.678
1       9       4       2015-07-02 08:22:56.123
2       2       6       2015-07-02 08:26:37.564
2       1       7       2015-07-02 08:27:33.109
2       0       8       2015-07-02 08:31:11.687
0       3       5       2015-07-02 08:40:01.345
1       4       2       2015-07-02 08:42:23.210

期望的输出:

recipe  prod1_sum   prod2_avg   timestamp_first             timestamp_last
0       14          3.6666      2015-07-02 08:10:34.357     2015-07-02 08:16:22.098
1       12          3           2015-07-02 08:22:14.678     2015-07-02 08:22:56.123
2       3           7           2015-07-02 08:26:37.564     2015-07-02 08:31:11.687
0       3           5           2015-07-02 08:40:01.345     2015-07-02 08:40:01.345
1       4           2           2015-07-02 08:42:23.210     2015-07-02 08:42:23.210

基本上,每个“组”连续行(当表按时间戳列排序时)的一个输出行具有相同的“配方”值。在输出中,prod1_sum 是“组”中 prod1 的总和,prod2_avg 是同一“组”中 prod2 的平均值,最后 2 列分别是组中的第一个和最后一个时间戳。显然,有几个不同的组具有相同的“配方”值,我确实希望为每个组提供一个输出行。

目前,我有一个丑陋的方式来获得这个基于几个请求和数据库之外的大量数据处理,我真的想避免,而且不值得展示。

我的问题确实是行的“分组”。如果我可以将它单独应用于每个组,我知道如何创建一个可以做我想做的事情的聚合函数。我研究过 windows 函数,但似乎这会按配方对所有值进行分组,不符合我需要尊重的“连续行”原则。

【问题讨论】:

    标签: sql postgresql aggregate-functions window-functions


    【解决方案1】:

    您可以使用以下查询:

    SELECT recipe, SUM(prod1) AS prod1_sum,
           AVG(prod2) AS prod2_avg, 
           MIN(timestamp) AS timestamp_first, MAX(timestamp) AS timestamp_last
    FROM (       
       SELECT recipe, prod1, prod2, timestamp,
              ROW_NUMBER() OVER (ORDER BY timestamp) 
              - 
              ROW_NUMBER() OVER (PARTITION BY recipe 
                                 ORDER BY timestamp) AS grp
       FROM mytable ) t
    GROUP BY recipe, grp
    ORDER BY timestamp_first
    

    这里的技巧是使用ROW_NUMBER 窗口函数来识别连续recipe 值的孤岛:grp 计算字段正是这样做的。

    Demo here

    【讨论】:

    • 这真是太棒了!您编写它的方式使其一目了然。我将深入研究文档以更好地了解详细信息(ROW_NUMBER() OVER,FROM mytable 之后的“t”,...),但我现在已经步入正轨。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多