在数据分析与业务处理中,经常会遇到“某组内的前几名”这种需求。本文将介绍如何使用 SQL 的窗口函数 RANK() 配合 OVER (PARTITION BY ...) 子句,实现分组内排名,并通过实战例子加深理解。


📘 1. 基础知识

📌 RANK() 函数

RANK() 是一种窗口函数,用于为结果集中的每一行分配排名,如果有并列情况,会跳过排名。例如:1、2、2、4(没有3)。

📦 OVER (PARTITION BY ...) 子句

该子句可将数据按指定字段进行“分组”,每组单独进行排名,常用于分部门、分类、分班级等场景。


🧪 2. 示例数据准备

我们创建一个 student_scores 表,模拟不同班级学生的成绩。

CREATE TABLE student_scores (
  id INT PRIMARY KEY,
  name VARCHAR(50),
  class VARCHAR(10),
  score INT
);

INSERT INTO student_scores (id, name, class, score)
VALUES (1, 'Alice', 'A', 85),
       (2, 'Bob', 'A', 90),
       (3, 'Charlie', 'B', 95),
       (4, 'David', 'B', 80),
       (5, 'Emma', 'A', 75),
       (6, 'Frank', 'B', 85);

🧮 3. 分组排名查询语句

下面 SQL 将按班级 class 分组,并对每组内的 score 进行降序排名:

SELECT id, name, class, score,
       RANK() OVER (PARTITION BY class ORDER BY score DESC) AS ranking
FROM student_scores;

📊 4. 查询结果展示

id name class score ranking
3 Charlie B 95 1
6 Frank B 85 2
4 David B 80 3
2 Bob A 90 1
1 Alice A 85 2
5 Emma A 75 3

🔍 每个班级内部的学生都根据成绩进行了降序排序,并正确分配了排名。


✅ 5. 总结

  • RANK() 适合需要考虑并列情况的分组排名。

  • OVER (PARTITION BY ...) 可分组进行窗口函数运算。

  • 实用场景如:班级成绩排名、部门销售排行、分类热度等。


💡 小贴士:

  • 如果你不希望有“跳跃排名”,可以用 DENSE_RANK()

  • 若不希望排名相同的数据共享名次,使用 ROW_NUMBER()

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐