kis*_*ore 2 sql postgresql window-functions
我试图通过编写一些示例查询来了解postgres中的PARTITION BY.我有一个测试表,我在其上运行查询.
id integer | num integer
___________|_____________
1 | 4
2 | 4
3 | 5
4 | 6
Run Code Online (Sandbox Code Playgroud)
当我运行以下查询时,我得到了我预期的输出.
SELECT id, COUNT(id) OVER(PARTITION BY num) from test;
id | count
___________|_____________
1 | 2
2 | 2
3 | 1
4 | 1
Run Code Online (Sandbox Code Playgroud)
但是,当我将ORDER BY添加到分区时,
SELECT id, COUNT(id) OVER(PARTITION BY num ORDER BY id) from test;
id | count
___________|_____________
1 | 1
2 | 2
3 | 1
4 | 1
Run Code Online (Sandbox Code Playgroud)
我的理解是COUNT是在属于分区的所有行中计算的.在这里,我用num分区行.分区中的行数是相同的,有或没有ORDER BY子句.为什么输出会有差异?
当您将一个order by聚合添加到用作窗口函数的聚合时,聚合将变为"运行计数"(或您使用的任何聚合).
在count(*)将返回的行数,直到基于指定的顺序对"当前".
以下查询显示与a一起使用的聚合的不同结果order by.随着sum()代替count()它有点更容易看到(在我看来).
with test (id, num, x) as (
values
(1, 4, 1),
(2, 4, 1),
(3, 5, 2),
(4, 6, 2)
)
select id,
num,
x,
count(*) over () as total_rows,
count(*) over (order by id) as rows_upto,
count(*) over (partition by x order by id) as rows_per_x,
sum(num) over (partition by x) as total_for_x,
sum(num) over (order by id) as sum_upto,
sum(num) over (partition by x order by id) as sum_for_x_upto
from test;
Run Code Online (Sandbox Code Playgroud)
将导致:
id | num | x | total_rows | rows_upto | rows_per_x | total_for_x | sum_upto | sum_for_x_upto
---+-----+---+------------+-----------+------------+-------------+----------+---------------
1 | 4 | 1 | 4 | 1 | 1 | 8 | 4 | 4
2 | 4 | 1 | 4 | 2 | 2 | 8 | 8 | 8
3 | 5 | 2 | 4 | 3 | 1 | 11 | 13 | 5
4 | 6 | 2 | 4 | 4 | 2 | 11 | 19 | 11
Run Code Online (Sandbox Code Playgroud)
Postgres手册中有更多示例
你的两个表达式是:
COUNT(id) OVER (PARTITION BY num)
COUNT(id) OVER (PARTITION BY num ORDER BY id)
Run Code Online (Sandbox Code Playgroud)
为什么您希望这些返回相同的值?出于某种原因,语法不同。
第一个返回每个num的总计数——本质上是连接聚合值。
第二个进行累积计数。它COUNT()为 的每一行id, 直到该ids 值的所有值都执行此操作。
请注意,此类累积计数通常会使用RANK()(或相关函数)实现。累积计数与 略有不同RANK()。累计计数实现:
COUNT(id) OVER (PARTITION BY num ORDER BY id RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
Run Code Online (Sandbox Code Playgroud)
RANK()略有不同。只有当ORDER BY键有联系时,差异才重要。
| 归档时间: |
|
| 查看次数: |
2605 次 |
| 最近记录: |