使用窗口函数运行求和

Posted

技术标签:

【中文标题】使用窗口函数运行求和【英文标题】:running sum with window function 【发布时间】:2019-05-14 06:02:51 【问题描述】:

我在一个表中有以下数据:

col1
---
1
2
5
9
10

我想用col1col1之前的值之差减去1的运行总和来更新表中的col2

col2 = col2.prev + col1 - col1.prev - 1

结果是:

col1  |  col2
--------------
  1   |  0
  2   |  0
  5   |  2
  9   |  5
 10   |  5

我尝试使用窗口函数:

SELECT sum(col1 - lag(col1) OVER (ORDER BY col1) - 1) AS col2 FROM table1

但这是不允许的 - 错误:聚合函数调用不能包含窗口函数调用

还有其他方法可以做到这一点吗?我知道我可以轻松地编写一个函数来循环遍历行,但我从我所读到的内容中得到的印象是,这种方法在大多数情况下效率不高且不鼓励使用。如果我有错误的印象,请纠正我。

【问题讨论】:

你能确认COL2中的输出应该是- 00255 OR 00355 它是 00255 - 因为 0+5-2-1=2、2+9-5-1=5、5+10-9-1=5,依此类推... 【参考方案1】:

错误:聚合函数调用不能包含窗口函数调用

显示此错误消息是因为不允许对通过窗口表达式生成的列应用聚合函数。也不允许应用第二个窗口表达式。解决方案是简单地将结果包装在 cte 中并在后续的 select 语句中应用第二个窗口表达式。

WITH mytable(col1) AS (
VALUES (1), (2), (5), (9), (10)
)
, lagdiff AS (
  SELECT
    col1
  , COALESCE(col1 - lag(col1) OVER (ORDER BY col1) - 1, 0) col2_
  FROM mytable
)
SELECT
  col1
, SUM(col2_) OVER (ORDER BY col1) col2
FROM lagdiff

产生输出:

 col1 | col2
------+------
    1 |    0
    2 |    0
    5 |    2
    9 |    5
   10 |    5
(5 rows)

【讨论】:

谢谢。 cte 是什么意思? cte 是公用表表达式的缩写,它是一个子查询,位于主查询之前,而不是直接位于 from 子句中。

以上是关于使用窗口函数运行求和的主要内容,如果未能解决你的问题,请参考以下文章

如何使用窗口函数“求和(DISTINCT <column>)OVER()”?

窗口函数:仅对另一列中的不同值求和

Mysql时间数据分段累加求和案例之子查询与SUM窗口函数

大数据Hive3.x数仓开发窗口函数案例:连续N次登录的用户;级联累加求和;分组TopN

sum over函数

如果为空,则在窗口函数的分区子句中使用默认值