MySQL8 排名窗口函数实战

在数据库查询与数据分析中,对数据分组并进行排名是一项常见任务。SQL 窗口函数为此提供了高效的解决方案。本文旨在阐明三个核心排名函数------RANK()DENSE_RANK()ROW_NUMBER()------的功能、差异及适用场景。

示例数据模型

以下说明将基于一张students表示例,该表记录了学生的班级与分数。其中,'A'班存在分数相同的学生,这有助于展示各函数的关键区别。

sql 复制代码
-- 表结构与数据
create table students
(
    id    int auto_increment primary key,
    name  varchar(50) not null,
    class varchar(10) null,
    score int         null
);

INSERT INTO students (name, class, score) VALUES
('甲', 'A', 85),
('乙', 'A', 90),
('丙', 'B', 95),
('丁', 'B', 80),
('张三', 'A', 90);

1. RANK(): 标准排名 (非连续)

RANK() 函数提供标准的排名功能。当存在数值相等的行时,这些行将获得相同的排名,但后续名次的序号将会跳跃。

查询语句:

sql 复制代码
select name, class, score, rank() over (partition by class order by score desc) as class_rank
from students;

结果:

name class score class_rank
A 90 1
张三 A 90 1
A 85 3
B 95 1
B 80 2

分析: 在 'A' 班中,'乙' 和 '张三' 因分数相同而并列第 1。随后的 '甲' 的排名为第 3,序列跳过了第 2 名。

2. DENSE_RANK(): 紧凑排名 (连续)

DENSE_RANK() 函数在处理并列排名时,不会在名次序列中产生间隙,确保排名是连续的。

查询语句:

sql 复制代码
select name, class, score, dense_rank() over (partition by class order by score desc) as class_rank
from students;

结果:

name class score class_rank
A 90 1
张三 A 90 1
A 85 2
B 95 1
B 80 2

分析: 在 'A' 班中,'乙' 和 '张三' 并列第 1 后,'甲' 的排名为第 2,名次序列保持了连续性。

3. ROW_NUMBER(): 行号分配 (唯一)

ROW_NUMBER() 函数不考虑数值的并列情况,它为分区内的每一行分配一个从 1 开始的、唯一的、连续的整数。

查询语句:

sql 复制代码
select name, class, score, row_number() over (partition by class order by score desc) as class_rank
from students;

结果:

name class score class_rank
A 90 1
张三 A 90 2
A 85 3
B 95 1
B 80 2

分析 : 即使 '乙' 和 '张三' 的分数相同,ROW_NUMBER() 依然为它们分配了 1 和 2 两个不同的序号。

功能对比与应用场景

函数 并列处理 排名是否连续 主要应用场景
RANK() 排名相同 不连续 (跳跃) 体育赛事等传统排名
DENSE_RANK() 排名相同 连续 (无间隙) 榜单排名,要求名次紧凑
ROW_NUMBER() 无并列排名 连续 分组获取 Top N 记录,数据去重

在实际应用中,应根据排名是否需要处理并列以及名次序列是否需要连续来选择合适的函数。

相关推荐
Mahir08几秒前
Spring 核心原理:IoC/DI 与 Bean 生命周期全景解析
java·后端·spring·面试·bean生命周期·控制反转ioc·依赖注入di
weixin_489690021 分钟前
NAS部署实测:Solon vs Spring Boot,从内存到包体积的“降维打击”
java·spring boot·后端
枕星而眠8 分钟前
数据结构哈希表(散列表)超详细总结
c语言·数据结构·后端·散列表
一条泥憨鱼8 分钟前
【Java 进阶】LinkedHashMap 与 TreeMap
java·开发语言·数据结构·笔记·后端·学习
Lee川9 小时前
mini-cursor 揭秘:从 Tool 定义到 Agent 循环的完整实现
前端·人工智能·后端
星浩AI11 小时前
OpenHuman 对比 OpenClaw、Hermes Agent
人工智能·后端·agent
小江的记录本11 小时前
【Java基础】泛型:泛型擦除、通配符、上下界限定(附《思维导图》+《面试高频考点清单》)
java·数据结构·后端·mysql·spring·面试·职场和发展
geovindu13 小时前
go: Semaphore Pattern
开发语言·后端·设计模式·golang·企业级信号量模式
IT_陈寒13 小时前
Redis内存用爆了,原来我们都忽略了这个配置
前端·人工智能·后端
武子康13 小时前
Java-02 深入浅出MyBatis 3 快速入门:环境配置、项目创建与 CRUD 操作
java·后端