四大排名函数
约 513 字大约 2 分钟
2025-02-02
Sql四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)
score表
数据
id | userId | score |
---|---|---|
1 | 1 | 100 |
2 | 2 | 90 |
3 | 3 | 95 |
4 | 1 | 92 |
5 | 2 | 92 |
6 | 3 | 100 |
sql语句
DROP TABLE if EXISTS score;
CREATE TABLE score (
id int PRIMARY KEY AUTO_INCREMENT,
userId int NOT NULL,
score int NOT NULL
);
INSERT INTO score (userId, score)
VALUES (1, 100),
(2, 90),
(3, 95),
(1, 92),
(2, 92),
(3, 100);
RANK
相同的值排名相同,下一名会跳过相应的名次(即存在“排名空缺”)
SELECT *, RANK() OVER (ORDER BY score DESC) AS `rank` FROM score;
id | userId | score | rank |
---|---|---|---|
1 | 1 | 100 | 1 |
6 | 3 | 100 | 1 |
3 | 3 | 95 | 3 |
4 | 1 | 92 | 4 |
5 | 2 | 92 | 4 |
2 | 2 | 90 | 6 |
DENSE_RANK
相同的值排名相同,但下一名不会跳过(即无“排名空缺”)
SELECT *, DENSE_RANK() OVER (ORDER BY score DESC) AS `dense_rank` FROM score;
id | userId | score | dense_rank |
---|---|---|---|
1 | 1 | 100 | 1 |
6 | 3 | 100 | 1 |
3 | 3 | 95 | 2 |
4 | 1 | 92 | 3 |
5 | 2 | 92 | 3 |
2 | 2 | 90 | 4 |
ROW_NUMBER
为每一行分配唯一的序号(即使值相同也不会并列)
SELECT *, ROW_NUMBER() OVER (ORDER BY score DESC) AS `row_number` FROM score;
id | userId | score | row_number |
---|---|---|---|
1 | 1 | 100 | 1 |
6 | 3 | 100 | 2 |
3 | 3 | 95 | 3 |
4 | 1 | 92 | 4 |
5 | 2 | 92 | 5 |
2 | 2 | 90 | 6 |
NTILE
将结果集按顺序平均分成 n 组(尽可能平均分配,但如果数据行数不能被n整除,则前面的组会比后面的组多1行)
SELECT *, NTILE(4) OVER (ORDER BY score DESC) AS `ntile` FROM score;
id | userId | score | ntile |
---|---|---|---|
1 | 1 | 100 | 1 |
6 | 3 | 100 | 1 |
3 | 3 | 95 | 2 |
4 | 1 | 92 | 2 |
5 | 2 | 92 | 3 |
2 | 2 | 90 | 4 |
rank, dense_rank, row_number区别
函数名 | 相同值是否相同排名 | 是否跳跃排名 | 是否唯一 |
---|---|---|---|
RANK() | ✅ 是 | ✅ 会跳跃 | ❌ 可能重复 |
DENSE_RANK() | ✅ 是 | ❌ 不跳跃 | ❌ 可能重复 |
ROW_NUMBER() | ❌ 否 | 🚫 不适用 | ✅ 唯一 |
示例对比
数据
id | userId | score | rank | dense_rank | row_number |
---|---|---|---|---|---|
1 | 1 | 100 | 1 | 1 | 1 |
6 | 3 | 100 | 1 | 1 | 2 |
3 | 3 | 95 | 3 | 2 | 3 |
4 | 1 | 92 | 4 | 3 | 4 |
5 | 2 | 92 | 4 | 3 | 5 |
2 | 2 | 90 | 6 | 4 | 6 |
sql语句
SELECT *,
RANK() OVER (ORDER BY score DESC) AS `rank`,
DENSE_RANK() OVER (ORDER BY score DESC) AS `dense_rank`,
ROW_NUMBER() OVER (ORDER BY score DESC) AS `row_number`
FROM score;