【发布时间】:2021-11-27 01:58:29
【问题描述】:
我知道它在 SQL-92 中是不允许的。但从那以后它可能已经改变了,特别是当应用了一个窗口时。你能解释一下这些变化并给出引入它们的版本(或版本,如果有的话)?
示例
-
SUM(COUNT(votes.option_id)) OVER() 是否符合标准 SQL:2016(或更早版本)的有效语法?
这是我在Why can you nest aggregate functions when using a window function in PostgreSQL? 中的comment(未回答,在这么老的问题中可能不太可能)。
- Codewars 上的 Calculating Running Total (SQL) kata 是其最受好评的解决方案(使用 PostgreSQL 13.0,一个高度符合标准的引擎,因此代码很可能是标准的):
SELECT
CREATED_AT::DATE AS DATE,
COUNT(CREATED_AT) AS COUNT,
SUM(COUNT(CREATED_AT)) OVER (ORDER BY CREATED_AT::DATE ROWS UNBOUNDED PRECEDING)::INT AS TOTAL
FROM
POSTS
GROUP BY
CREATED_AT::DATE
(可以简化为:
SELECT
created_at::DATE date,
COUNT(*) COUNT,
SUM(COUNT(*)) OVER (ORDER BY created_at::DATE)::INT total
FROM posts
GROUP BY created_at::DATE
我认为::s 是一种我不知道的新语法。现在允许从 TIMESTAMP 转换为 DATE(在 SQL-92 中不允许)。)
- 正如this SO answer 解释的那样,即使没有窗口,Oracle 数据库也允许它从上下文中提取
GROUP BY。我不知道标准是否允许。
【问题讨论】:
-
这是关于聚合(COUNT、SUM、MAX 等)和分析函数(COUNT、SUM、MAX OVER 等)。聚合(在您的示例中为
COUNT(*))首先发生。然后,您可以在结果上应用分析函数(在您的示例中为SUM OVER)。 -
Oracle 是个例外。在那里你可以嵌套两个聚合函数。这不符合标准,虽然我经常使用 Oracle,但我从不使用它。
-
::是 PostgreSQL 中的转换运算符。它不符合标准。 -
@ThorstenKettner,您能否详细说明分析函数以及它们与聚合函数的区别?文档“信息技术 - 数据库语言 - SQL - 第 2 部分:基础(SQL/Foundation)”(我使用的是SQL:2011 late draftlinked from Wikipedia)甚至没有包含“分析”这个词。
-
我很抱歉造成混乱。 “分析函数”只是“窗口函数”的另一个词。在 SQL 标准中,他们只使用术语“窗口函数”。我仍然添加了一个答案来更详细地解释差异。
标签: sql language-lawyer aggregate-functions window-functions sql-standards