使用 Order By 计算分区中的行数

新手上路,请多包涵

我试图通过编写一些示例查询来理解 postgres 中的 PARTITION BY 。我有一个运行查询的测试表。

 id integer | num integer
___________|_____________
1          | 4
2          | 4
3          | 5
4          | 6

当我运行以下查询时,我得到了预期的输出。

 SELECT id, COUNT(id) OVER(PARTITION BY num) from test;

id         | count
___________|_____________
1          | 2
2          | 2
3          | 1
4          | 1

但是,当我将 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

我的理解是 COUNT 是在属于分区的所有行中计算的。在这里,我按 num 对行进行了分区。分区中的行数是相同的,有或没有 ORDER BY 子句。为什么输出会有差异?

原文由 kishore 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 658
1 个回答

当您将 order by 添加到用作窗口函数的聚合时,聚合变成“运行计数”(或您使用的任何聚合)。

count(*) 将根据指定的顺序返回“当前行”之前的行数。

以下查询显示了与 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;

将导致:

 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

Postgres 手册 中有更多示例

原文由 a_horse_with_no_name 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进