postgresql Postgres窗口函数计数(*),意外结果

ee7vknir  于 5个月前  发布在  PostgreSQL
关注(0)|答案(1)|浏览(49)

在Postgres做了15年的繁重工作之后,现在我第一次发现了一个意想不到的结果,处理一个窗口函数。
下面是一个例子,如果添加order by ...,则count(*) over (partition 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)


我需要额外的“命令”来确定谁是组长。
提前感谢Ariel Tejera

xv8emn3q

xv8emn3q1#

你忘记了窗口函数中的frame子句以及它的默认值;请参阅文档:
默认的框架选项是RANGE UNBOUNDED PRECEDING,这与RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW相同。使用ORDER BY,这将框架设置为从分区开始到当前行的最后一个ORDER BY对等体的所有行。没有ORDER BY,这意味着分区的所有行都包含在窗口框架中,因为所有行都成为当前行的对等体。
因此,第二个查询生成一个“运行计数”,它将给您与row_number()相同的结果给予。

相关问题