Postgres窗口函数

Postgres窗口函数简单使用

定义

官方文档对窗口函数的解释:

A window function performs a calculation across a set of table rows that are somehow related to the current row. This is comparable to the type of calculation that can be done with an aggregate function. However, window functions do not cause rows to become grouped into a single output row like non-window aggregate calls would. Instead, the rows retain their separate identities. Behind the scenes, the window function is able to access more than just the current row of the query result.

我的理解:

窗口函数可以在保留明细的情况下获取聚合结果

使用示例

假如存在一张工资表(salary_detail),这个包含三列:部门,员工编号,工资。如下所示:

departmentempnosalary
摸鱼11000
摸鱼22000
摸鱼33000
钓虾14000
钓虾25000
钓虾36000
偷螃蟹17000
偷螃蟹28000
偷螃蟹39000

计算平均月薪

如果我们只希望得到每个部门的平均月薪,那么根据部门分组,然后取月薪的均值即可:

select department,
       avg(salary) as dep_avg_salary
from salary_detail
group by 1;
departmentdep_avg_salary
摸鱼2000
钓虾5000
偷螃蟹8000

在不使用窗口函数的情况下,如果需要在每行salary_detail表数据的基础上派生出部门平均工资,我们需要通过子查询实现:

with t1 as
  (select department,
          avg(salary) as avg_salary
   from salary_detail
   group by 1)
select t2.department,
       t2.empno,
       t2.salary,
       t1.dep_avg_salary
from salary_detail t2
left join t1 on t2.department = t1.department;

同样的结果,也可以通过窗口函数搞定:

-- 下面两个sql是等价的
-- 1
select department,
       empno,
       salary,
       (avg(salary) over (partition by department)) as dep_avg_salary
from empsalary;

-- 2
select department,
       empno,
       salary,
       (avg(salary) over w) as dep_avg_salary
from empsalary
window w as (partition by department);
departmentempnosalarydep_avg_salary
摸鱼110002000
摸鱼220002000
摸鱼330002000
钓虾140005000
钓虾250005000
钓虾360005000
偷螃蟹170008000
偷螃蟹280008000
偷螃蟹390008000

找出每个部分月薪前两名的人

with t as (
select department, empno, salary,
       (rank() over (partition by department order by salary desc)) as rank
from empsalary)
select * from t where rank <= 2;

结尾

本文只是窗口函数非常简单的应用,可查阅 官方文档 寻找更多复杂的场景。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值