`OVER` 子句中的 `ORDER BY` 和 `PARTITION BY` 参数有什么区别?

Zac*_*ith 9 window-functions

下面的这些查询都给了我完全相同的结果,我认为这是因为我的数据集而不是参数如何工作。

使用OVER子句时,ORDER BY和之间有什么区别PARTITION BY

稍微不同的是,为什么不使用该术语GROUP BY而不是更复杂的声音PARTITION BY,因为在这种情况下使用分区似乎与分组实现了相同的目的。我知道您可以更改这些内部分区,然后这些更改会反映在表中。是这个原因吗?

查询 1:

SELECT
    CP.iYear,
    AVG(AVG(CP.mUpgradeCost)) OVER(ORDER BY iYear) AS [avg]
FROM ProForma.dbo.CapitalProject CP
GROUP BY CP.iYear
Run Code Online (Sandbox Code Playgroud)

查询 2:

SELECT
    CP.iYear,
    AVG(AVG(CP.mUpgradeCost)) OVER(PARTITION BY iYear) AS [avg]
FROM ProForma.dbo.CapitalProject CP
GROUP BY CP.iYear
Run Code Online (Sandbox Code Playgroud)

Dan*_*her 14

PARTITION BY作品为“窗组”和ORDER BY组内做了排序。但是,因为您使用的是GROUP BY CP.iYear,所以您可以有效地将窗口减少到仅一行(在窗口函数之前GROUP BY执行)。在您的情况下,单行的平均值将是该行的值。AVG(CP.mUpgradeCost)

至于查询 2,你是想创建一个运行平均值还是什么?甚至不确定您希望该查询返回什么。

如果您删除GROUP BY CP.iYear并更改AVG(AVG(...))为 just AVG(),您将看到不同之处。

这是一个希望解释PARTITION BY和/或使用的示例ORDER BY

随机表:

a     b
----- ------
X     1001
X     1002
X     1003
Y     1001
Y     1002
Run Code Online (Sandbox Code Playgroud)

现在,

SELECT a, b, COUNT(*) OVER (PARTITION BY a) FROM r;
Run Code Online (Sandbox Code Playgroud)

将返回

a     b
----- ------ ------
X     1001   3
X     1002   3
X     1003   3
Y     1001   2
Y     1002   2
Run Code Online (Sandbox Code Playgroud)

所以你可以看到有 3 行 a=X 和 2 行 a=Y。ORDER BY当你想要一个有序的窗口函数时,这个子句就会发挥作用,比如行号或运行总数。

SELECT a, b, ROW_NUMBER() OVER (PARTITION BY a ORDER BY b),
             SUM(b) OVER (PARTITION BY a ORDER BY b ROWS UNBOUNDED PRECEDING)
FROM r;
Run Code Online (Sandbox Code Playgroud)

... 给你:

a     b
----- ------ ------ ------
X     1001   1      1001
X     1002   2      2003
X     1003   3      3006
Y     1001   1      1001   <- row number and running total resets here; new partition
Y     1002   2      2003
Run Code Online (Sandbox Code Playgroud)