postgresql 分类排名

本文详细介绍了PostgreSQL中的排名窗口函数,如ROW_NUMBER,RANK,DENSE_RANK,PERCENT_RANK,CUME_DIST和NTILE,以及如何在按部门排序员工月薪时使用这些函数。特别关注了CUME_DIST的累积分布和NTILE的等分功能。

排名窗口函数

排名窗口函数用于对数据进行分组排名。常见的排名窗口函数包括:
ROW_NUMBER,为分区中的每行数据分配一个序列号,序列号从 1 开始分配。
RANK,计算每行数据在其分区中的名次;如果存在名次相同的数据,后续的排名将会
产生跳跃。
DENSE_RANK,计算每行数据在其分区中的名次;即使存在名次相同的数据,后续的
排名也是连续的值。
PERCENT_RANK,以百分比的形式显示每行数据在其分区中的名次;如果存在名次相
同的数据,后续的排名将会产生跳跃。
CUME_DIST,计算每行数据在其分区内的累积分布,也就是该行数据及其之前的数据
的比率;取值范围大于 0 并且小于等于 1。
NTILE,将分区内的数据分为 N 等份,为每行数据计算其所在的位置。
排名窗口函数不支持动态的窗口大小(frame_clause),而是以当前分区作为分析的窗口。

示例

按照部门为单位,计算员工的月薪排名:

select
first_name,last_name,department_id,salary,
row_number() over(partition by department_id order by salary desc),
rank() over(partition by  department_id order by salary desc),
dense_rank() over(partition by  department_id order by salary desc),
percent_rank() over(partition by  department_id order by salary desc)
from employees;

在这里插入图片描述
以上示例中 4 个窗口函数的 OVER 子句完全相同,此时可以采用一种更简单的写法:

select
first_name,last_name,department_id,salary,
row_number() over w,
rank() over w,
dense_rank() over w,
percent_rank() over w
from employees
window w as  (partition by  department_id order by salary desc);

CUME_DIST 和 NTILE

select
first_name,last_name,department_id,salary,
cume_dist() over w,
ntile(6) over w
from employees
window w as  (partition by department_id order by salary desc);

在这里插入图片描述

### PostgreSQL 窗口函数使用指南 PostgreSQL 是一个功能强大的开源关系数据库管理系统,广泛应用于数据分析、Web 应用和企业级解决方案中。窗口函数是 PostgreSQL 中的一项重要特性,它允许在不减少行数的前提下,对一组相关行执行计算,从而实现复杂的数据分析任务 [^1]。 #### 窗口函数的基本语法结构如下: ```sql function_name() OVER ( [PARTITION BY <分组列>] [ORDER BY <排序列>] [windowing_clause] ) ``` 窗口函数与传统聚合函数不同之处在于,它不会将多行合并为一行输出,而是在每一行上保留原始数据,并附加基于窗口定义的计算值 。 #### 常见窗口函数分类及用途: - **排名函数**: - `ROW_NUMBER()`:为每一行分配唯一的序号。 - `RANK()`:相同值并列,后续排名跳跃。 - `DENSE_RANK()`:相同值并列,但排名连续 [^2]。 - **聚合窗口函数**: - `SUM()`, `AVG()`, `MIN()`, `MAX()`:在窗口范围内进行聚合计算。 - 常用于累计总和、区间平均值等场景 。 - **偏移函数**: - `LAG(column, offset, default)`:访问当前行之前的某一行数据。 - `LEAD(column, offset, default)`:访问当前行之后的某一行数据 [^1]。 - **分布函数**: - `CUME_DIST()`:计算当前行在窗口中的累积分布。 - `PERCENT_RANK()`:计算当前行的百分比排名 。 #### 示例:使用 ROW_NUMBER() 进行分组排名 ```sql SELECT employee_id, department_id, salary, ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank FROM employees; ``` 该查询将按部门分组,对员工工资进行降序排列,并为每位员工分配一个部门内的排名 [^2]。 #### 示例:使用 LAG 函数比较前后行数据 ```sql SELECT employee_id, salary, LAG(salary, 1, 0) OVER (ORDER BY salary DESC) AS prev_salary FROM employees; ``` 该查询将显示每位员工的工资及其前一位员工的工资,便于进行数据比较 [^1]。 #### 示例:使用 SUM 窗口函数进行累计计算 ```sql SELECT order_date, amount, SUM(amount) OVER (ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total FROM orders; ``` 该查询将按订单日期顺序累计订单金额,生成运行总和 。 #### 窗口函数与 GROUP BY 的区别: - `GROUP BY` 会将数据合并为一组,每组只保留一行结果。 - 窗口函数则保留原始行数,同时添加基于窗口定义的计算值,适用于需要保留明细数据并附加聚合或排名信息的场景 [^1]。 #### 窗口函数的应用场景: - **排名分析**:如销售排名、成绩排名。 - **趋势分析**:如计算移动平均、增长率。 - **数据比较**:如比较当前行与前一行的数据。 - **窗口聚合**:如计算累计总和、区间平均值 。 PostgreSQL 的窗口函数功能非常强大,结合地理空间分析工具(如 PostGIS),可以实现更高级的数据分析任务。例如,以下查询展示了如何结合 `ST_Distance` 和 `RANK()` 进行地理距离排名 [^3]: ```sql SELECT location, timestamp, ST_Distance(location, 'POINT(0 0)') AS distance, RANK() OVER (ORDER BY distance) AS rank FROM gps_logs; ``` 该查询计算了每个 GPS 点与原点之间的距离,并对这些距离进行排名。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值