在MySQL中,RANK()
, DENSE_RANK()
, 和 ROW_NUMBER()
是窗口函数,它们可以用于对查询结果集中的行进行排名。这些函数通常与 OVER()
子句一起使用,以定义排名的窗口和排序的规则。下面是每种函数的基本用法和区别:
- RANK() OVER():
RANK()
函数为结果集中的每一行分配一个排名。- 如果存在相同的值,则会跳过排名(例如,如果两行并列第一,则下一个排名是3而不是2)。
- 语法:
RANK() OVER(partition_by_clause order_by_clause)
- DENSE_RANK() OVER():
DENSE_RANK()
函数与RANK()
类似,但是它不会跳过排名。- 如果存在并列的排名,后续的排名会连续分配(例如,如果两行并列第一,则下一个排名是2)。
- 语法:
DENSE_RANK() OVER(partition_by_clause order_by_clause)
- ROW_NUMBER() OVER():
ROW_NUMBER()
函数为结果集中的每一行分配一个唯一的序号。- 它不考虑值是否相同,序号会连续递增。
- 语法:
ROW_NUMBER() OVER(partition_by_clause order_by_clause)
这里的 partition_by_clause
是可选的,它允许你将数据分成不同的分区,每个分区内部进行排名。如果没有指定分区,则整个结果集作为一个分区。
order_by_clause
是必需的,它定义了排名的排序规则,可以基于一个或多个列。
例如,假设有一个名为 employees
的表,包含 id
, name
, 和 salary
列,假设我们有以下员工数据和工资:
id | name | salary |
---|---|---|
1 | Alice | 70000 |
2 | Bob | 60000 |
3 | Charlie | 60000 |
4 | David | 50000 |
你可以使用以下查询来为员工的工资进行排名:
SELECT
id,
name,
salary,
RANK() OVER (ORDER BY salary DESC) AS rank,
DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_number
FROM
employees;
这个查询将返回每个员工的ID、姓名、工资,以及他们的排名、密集排名和行号,根据工资降序排列。
id | name | salary | rank | dense_rank | row_number |
---|---|---|---|---|---|
1 | Alice | 70000 | 1 | 1 | 1 |
2 | Bob | 60000 | 2 | 2 | 2 |
3 | Charlie | 60000 | 2 | 2 | 3 |
4 | David | 50000 | 3 | 3 | 4 |