postgresql-聚合窗口函数
- 聚合函数
- 排名窗口函数
- 案例1
- 案例2
- 取值窗口函数
- 环比增长率
- 同比增长率
聚合函数
常用的聚合函数,例如 AVG、SUM、COUNT 等,也可以作为窗口函数使用
--计算移动平均值
select saledate, amount, avg(amount) over (order by saledate rows between 1
preceding and 1 following)from sales_data
where product = '桔子' and channel = '淘宝';
排名窗口函数
案例1
-- 计算员工部门薪资排名
select
e.first_name,
e.last_name ,
e.department_id ,
e.salary,
row_number() over(partition by e.department_id order by e.salary),
rank() over(partition by e.department_id order by e.salary) ,
dense_rank() over(partition by e.department_id order by e.salary) ,
percent_rank() over(partition by e.department_id order by e.salary)
from employees e;
4 个窗口函数的 OVER 子句完全相同,此时可以采用一种更简单的写法
-- 计算员工部门薪资排名
select
e.first_name,
e.last_name ,
e.department_id ,
e.salary,
row_number() over w,
rank() over w ,
dense_rank() over w ,
percent_rank() over w
from employees e
-- 定义窗口(在sql语句的最后)
window w as (partition by e.department_id order by e.salary)
;
案例2
-- 计算员工部门薪资排名
select
e.first_name,
e.last_name ,
e.department_id ,
e.salary,
cume_dist() over w as "累积占比",
ntile(5) over w as "相对位置"from employees e
-- 定义窗口(在sql语句的最后)
window w as (partition by e.department_id order by e.salary)
;
取值窗口函数
取值窗口函数用于返回指定位置上的数据。常见的取值窗口函数包括:
- FIRST_VALUE,返回窗口内第一行的数据
- LAST_VALUE,返回窗口内最后一行的数据
- NTH_VALUE,返回窗口内第 N 行的数据
- LAG,返回分区中当前行之前的第 N 行的数据
- LEAD,返回分区中当前行之后第 N 行的数据
其中,LAG 和 LEAD 函数不支持动态的窗口大小(frame_clause),而是以当前分区作为分析的窗口。
/** first_value、last_value 以及 NTH 函数分别获取每个部门内部月薪最高、月薪最低以及月薪第三高的员工* */
select
e.first_name,
e.last_name ,
e.department_id ,
e.salary ,
first_value(e.salary) over(partition by e.department_id order by e.salary),
last_value(e.salary) over(partition by e.department_id order by e.salary),
nth_value(e.salary,3) over(partition by e.department_id order by e.salary)
from employees e;
环比增长率
LAG 和 LEAD 函数同样用于计算销量数据的环比/同比增长
-- 首先,创建一个通用表表达式 sales_monthly,得到了不同产品每个月的销量汇总;
-- LAG(sum_amount, 1)表示获取上一期的销量;当前月份的销量减去上个月的销量,再除以上个月
-- 的销量,就是环比增长率
WITH sales_monthly AS (SELECT product, to_char(saledate,'YYYYMM') ym, sum(amount) sum_amountFROM sales_dataGROUP BY product, to_char(saledate,'YYYYMM')
)
SELECT product AS "产品", ym "年月", sum_amount "销量",(sum_amount - LAG(sum_amount, 1) OVER (PARTITION BY product ORDER BY
ym))/LAG(sum_amount, 1) OVER (PARTITION BY product ORDER BY ym) * 100 AS "
环比增长率(%)"FROM sales_monthly
ORDER BY product, ym;
同比增长率
-- 2019年1月份数据 -2018年1月份数据,然后再和2018年1月份数据进行对比
-- 两年之间的相同月份
select
s.*,
100*(s.amount - lag(s.amount,12) over(partition by s.product order by s.ym))
/ lag(s.amount,12 ) over(partition by s.product order by s.ym) as "同比增长率"
from
sales_monthly s;