-- 三种排名函数对比
SELECT
emp_name,
dept,
score,
ROW_NUMBER() OVER (PARTITION BY dept ORDER BY score DESC) as row_num,
RANK() OVER (PARTITION BY dept ORDER BY score DESC) as rank,
DENSE_RANK() OVER (PARTITION BY dept ORDER BY score DESC) as dense_rank
FROM performance
ORDER BY dept, row_num;
结果说明:
emp_name
dept
score
row_num
rank
dense_rank
Alice
Engineering
95
1
1
1
Carol
Engineering
95
2
1
1
Bob
Engineering
85
3
3
2
Eve
Marketing
92
1
1
1
David
Marketing
88
2
2
2
Frank
Marketing
78
3
3
3
Grace
HR
90
1
1
1
Henry
HR
85
2
2
2
排名函数区别
函数
并列处理
序号连续性
ROW_NUMBER()
ROW_NUMBER()
随机分配不同序号
连续
RANK()
RANK()
并列相同,后续跳号
不连续(1,1,3)
DENSE_RANK()
DENSE_RANK()
并列相同,后续连续
连续(1,1,2)
百分比排名
使用
PERCENT_RANK()
PERCENT_RANK()
计算员工在部门内的相对位置(0 到 1 之间)。
-- 计算百分比排名
SELECT
emp_name,
dept,
score,
ROUND(PERCENT_RANK() OVER (PARTITION BY dept ORDER BY score DESC), 2) as pct_rank
FROM performance
ORDER BY dept, pct_rank DESC;
结果说明:
emp_name
dept
score
pct_rank
Alice
Engineering
95
0
Carol
Engineering
95
0
Bob
Engineering
85
0.5
Eve
Marketing
92
0
David
Marketing
88
0.5
Frank
Marketing
78
1
Grace
HR
90
0
Henry
HR
85
1
💡 提示:
PERCENT_RANK
PERCENT_RANK
值越小表示排名越靠前(0 为第一名)。
前后行对比
使用
LAG()
LAG()
和
LEAD()
LEAD()
访问当前行的前一行或后一行数据,常用于计算环比变化。
-- 计算部门内员工的分数差值
SELECT
emp_name,
dept,
score,
LAG(score, 1) OVER (PARTITION BY dept ORDER BY score DESC) as prev_score,
score - LAG(score, 1) OVER (PARTITION BY dept ORDER BY score DESC) as diff
FROM performance
ORDER BY dept, score DESC;
结果说明:
emp_name
dept
score
prev_score
diff
Alice
Engineering
95
NULL
NULL
Carol
Engineering
95
95
0
Bob
Engineering
85
95
-10
Eve
Marketing
92
NULL
NULL
David
Marketing
88
92
-4
Frank
Marketing
78
88
-10
Grace
HR
90
NULL
NULL
Henry
HR
85
90
-5
⚠️ 注意:第一行的
LAG
LAG
返回
NULL
NULL
,在数值显示中可能显示为
nan
nan
,但
IS NULL
IS NULL
判断仍然有效。
移动平均
使用窗口帧(ROWS BETWEEN)计算滑动窗口的统计值,适用于趋势分析。
-- 计算部门内按分数排序的移动平均(当前行及前两行)
SELECT
emp_name,
dept,
score,
ROUND(AVG(score) OVER (
PARTITION BY dept
ORDER BY score DESC
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
), 1) as moving_avg_3
FROM performance
ORDER BY dept, score DESC;
结果说明:
emp_name
dept
score
moving_avg_3
Alice
Engineering
95
95
Carol
Engineering
95
95
Bob
Engineering
85
91.7
Eve
Marketing
92
92
David
Marketing
88
90
Frank
Marketing
78
86
Grace
HR
90
90
Henry
HR
85
87.5
分位数计算
使用
PERCENTILE()
PERCENTILE()
函数计算数据的分位数,如中位数(0.5)、四分位数(0.25, 0.75)。
-- 计算各部门分数的中位数和四分位数
SELECT
dept,
PERCENTILE(score, 0.5) as median,
PERCENTILE(score, 0.25) as q1,
PERCENTILE(score, 0.75) as q3,
MIN(score) as min_score,
MAX(score) as max_score
FROM performance
GROUP BY dept
ORDER BY dept;