Postgres窗口函数count(*),意想不到的结果

问题描述 投票:0回答:1

在使用 Postgres 完成繁重工作 15 年后,现在我第一次发现了一个意想不到的结果,即处理窗口函数。

这是一个示例,如果添加

count(*) over (partition by ...
order by ...
就会被破坏:

create temp view cc as
select * from
(   values
    (1,1),
    (1,2),
    (2,1),
    (2,2),
    (2,3)
) as t(key1, key2) ;

select *,                       -- correct result
    count(*) over (             -- count(*) works, order unspecified
        partition by key1
    )
from cc order by key1,key2;

select *,                       -- incorrect result
    count(*) over (             -- count(*) fails, order is specified
        partition by key1 order by key2
    )
from cc order by key1,key2;

上面的例子产生:

 key1 | key2 | count      -- correct result
------+------+-------
    1 |    1 |     2      
    1 |    2 |     2
    2 |    1 |     3
    2 |    2 |     3
    2 |    3 |     3
(6 rows)

 key1 | key2 | count      -- incorrect result
------+------+-------
    1 |    1 |     1      -- should be 2
    1 |    2 |     2      
    2 |    1 |     1      -- should be 3
    2 |    2 |     2      -- should be 3
    2 |    3 |     3
(6 rows)

我需要额外的“排序者”来确定谁是组长。

提前致谢, 阿里尔·特赫拉

sql postgresql window-functions
1个回答
0
投票

您忘记了窗口函数中的框架子句及其默认值;请参阅文档

默认的取景选项是

RANGE UNBOUNDED PRECEDING
,与
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
相同。使用
ORDER BY
,这会将框架设置为从分区开始到当前行的最后一个
ORDER BY
对等点的所有行。如果没有
ORDER BY
,这意味着分区的所有行都包含在窗口框架中,因为所有行都成为当前行的对等行。

因此,您的第二个查询会生成一个“运行计数”,这将为您提供与

row_number()
相同的结果。

© www.soinside.com 2019 - 2024. All rights reserved.