窗口SUM函数如何在内部使用OVER



我正在努力理解窗口函数是如何在内部工作的。

ID,Amt
A,1
B,2
C,3
D,4
E,5

如果我运行这个,将针对每条记录给出total列中所有金额的总和。

Select ID, SUM (AMT) OVER () total from table

但当我运行这个时,它会给我累计的

Select ID, SUM (AMT) OVER (order by ID) total from table 

试图了解当其OVER()OVER(order by ID)

我所理解的是,当OVER中没有定义分区时,它会将所有内容视为单个分区。但不明白当我们在over()中加上order by Id时,它为什么开始做累积和?

有人能分享一下幕后发生的事情吗?

这是一个有趣的案例,基于文档,这里是解释和示例。

如果没有指定PARTITION BY,函数将处理查询结果集为单个分区。功能将应用于如果您没有指定ORDERBY子句,那么分区中的所有行。

因此,如果指定ORDER BY,则

如果指定了ROWS/RANGE,则默认RANGE UNBOUNDED PREEDING AND CURRENT ROW用作可接受可选ROWS/RANGE的功能的窗口框架规格(例如最小值或最大值(。

所以从技术上讲,这两个命令是相同的:

SELECT ID, SUM(AMT) OVER (ORDER BY ID) total FROM table
SELECT ID, SUM(AMT) OVER (ORDER BY ID RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) total FROM table

有关详细信息,请参阅文档:https://learn.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql?view=sql-服务器-ver15

这与Oracle本身无关,但它是SQL标准的一部分,在许多数据库中表现相同,包括Oracle、DB2、PostgreSQL、SQL Server、MySQL、MariaDB、H2等。

根据定义,当包含ORDER BY子句时,引擎将生成";运行值";(累积聚合(在每个分区内;如果没有ORDER BY子句,它将生成聚合整个分区的相同的单个值。

现在,分区本身主要由PARTITION BY子句定义。在没有它的情况下,整个结果集被认为是一个单独的分区。

最后,作为一个更高级的主题,可以使用";框架";子句(ROWSRANGE(;帧排除";条款(EXCLUDE(。

最新更新