在子查询中使用聚合和窗口函数

Posted

技术标签:

【中文标题】在子查询中使用聚合和窗口函数【英文标题】:Using aggregate and window function within a sub-query 【发布时间】:2019-09-29 23:21:00 【问题描述】:

我有一个使用SUM() OVER 的子查询的查询。虽然子查询本身可以正常工作,但在外部查询的上下文中使用时,不会应用聚合。

我制作了这个测试用例来近似我想要做的事情:

CREATE TEMPORARY TABLE TestNumbers
  (id INTEGER PRIMARY KEY, number INTEGER);
INSERT INTO TestNumbers (number)
  VALUES (10), (15), (20), (25), (30);

SELECT SUM(number) OVER (ORDER BY id) FROM TestNumbers;

这将返回预期结果...所有值的滚动总和。 10254570100

但是,如果我将其用作子查询...

SELECT (
  SELECT SUM(number) OVER (ORDER BY id)
) FROM TestNumbers;

我得到一个未应用聚合的结果。 10, 15, 20, 25, 30.

如何在子查询中将此聚合与 OVER 一起使用?

【问题讨论】:

我不明白你的问题。你提到了update,但剩下的问题只有selects。 @GordonLinoff 是的,抱歉,我试图将其分解为最简单的可重现形式,但认为其原因至少需要一些解释。我想如果我能让SELECT 与内部SELECT 一起工作,我会让UPDATE 没问题。 @GordonLinoff 删除了关于 UPDATE 的令人困惑的内容。感谢您查看我的问题! 【参考方案1】:

我很惊讶这竟然有效:

SELECT (SELECT SUM(number) OVER (ORDER BY id))
FROM TestNumbers;

我的意思是,确实如此。基本上,子查询是相关子查询,因此它针对外部查询中的每一行运行。也就是说,每次运行只有一个值——来自外部查询的相关值。那只是返回数字。

不清楚你真正想要做什么。

当我第一次阅读查询时,我以为是:

SELECT *
FROM (SELECT SUM(number) OVER (ORDER BY id))
      FROM TestNumbers
     ) tn

这很好,适用于累积值。

FROM 移动到子查询中:

SELECT (SELECT SUM(number) OVER (ORDER BY id))
        FROM TestNumbers
       )

由于子查询返回多行而中断查询。

【讨论】:

感谢您的回答。是的,我查询单个值的原因是我试图做一个UPDATE table SET col= ( /* subquery */),这个测试是我试图做的一个近似值,并模拟了我遇到的问题。不幸的是,子查询中的FROM 有效,但是因为我还需要在UPDATE 中设置表,所以外部查询会破坏内部查询。我会想出一个更好的例子并发布一个新问题。谢谢你回答这个问题!

以上是关于在子查询中使用聚合和窗口函数的主要内容,如果未能解决你的问题,请参考以下文章

SQL滑动窗口聚合(不使用窗口函数)

Hive之窗口函数

窗口聚合函数与分组聚合函数的异同

在子查询的FROM中使用Postgres窗口语句

MySQL窗口函数_聚合函数

重学SQL窗口函数