PostgeSQL:窗口函数在视图中表现不同

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

具有一列tmp_year_test.year 和值的示例表:

2010
2011
2012

现在逻辑

-- 2010 - OK
select
    max(year) over () as max_year
from tmp_year_test
where year = 2010

-- let's put it in the view
create view tmp_max_year_test as
select  
    year, 
    max(year) over () as max_year
from tmp_year_test

-- 2012 - WHY?
select  
    max_year
from tmp_max_year_test
where year = 2010

我以为我正在获取与没有视图时相同的列,但值不同。为什么? 我需要存储风。视图中的功能逻辑并对其进行过滤。有办法实现吗?

sql postgresql window-functions sql-view
2个回答
2
投票

创建视图时,窗口函数中没有

partition by
子句,所以聚合函数是作用在整个表上的。由于 2012 年是源表中所有值的最大值,因此视图包含各种年份 (
year
) 和常数值
2012
作为
max_year
.

doc 有一个非常相似的例子并添加了

SELECT salary, sum(salary) OVER () FROM empsalary;

上图,由于OVER子句中没有ORDER BY,窗口框架 与分区相同,因为缺少 PARTITION BY 是 整张桌子;换句话说,每笔款项都占满了整个表格,并且 所以我们对每个输出行得到相同的结果。

在第一个查询中,您将

max
计算限制在一行中,即 2010 年的那一行,因此 max_year 也是 2010.

要在使用视图时达到类似的效果,需要在

partition
子句中指定一个
over

create or replace view tmp_max_year_test as
select  
    year, 
    max(year) over (PARTITION BY year) as max_year
from tmp_year_test;

1
投票

您的视图有这3条记录:

select  
    year, 
    max(year) over () as max_year
from tmp_year_test

记录:

最大年
2010 2012
2011 2012
2012 2012

所以,当问:

select  
    max_year
from tmp_max_year_test
where year = 2010

返回

2012
似乎很合乎逻辑......

参见:DBFIDDLE 了解完整的 SQL 内容。

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