MariaDB RANK() 函数的基础用法与实例

MariaDB RANK() 函数用于为分组内的行分配排名。它可以为相同值的行分配相同的排名,并为下一个不同值的行分配下一个连续排名。

发布于

MariaDB RANK() 函数用于为分组内的行分配排名。它可以为相同值的行分配相同的排名,并为下一个不同值的行分配下一个连续排名。

语法

MariaDB RANK() 函数的语法如下:

RANK() OVER (
    PARTITION BY ...
    ORDER BY ...
)
  • PARTITION BY 子句用于指定要分组的列。
  • ORDER BY 子句用于指定排序规则。
  • RANK() 函数必须与 OVER 子句一起使用。

实例

按单列排名

此实例演示了如何按照单列进行排名。

DROP TABLE IF EXISTS scores;
CREATE TABLE scores (
  name VARCHAR(10),
  subject VARCHAR(10),
  score INT
);

INSERT INTO scores VALUES
  ('张三', '语文', 89),
  ('李四', '语文', 79),
  ('王五', '语文', 98),
  ('张三', '数学', 90),
  ('李四', '数学', 76),
  ('王五', '数学', 92);

SELECT
  name, subject, score,
  RANK() OVER (ORDER BY score DESC) AS `rank`
FROM scores;

以下是该语句的输出:

+--------+---------+-------+------+
| name   | subject | score | rank |
+--------+---------+-------+------+
| 王五   | 语文    |    98 |    1 |
| 王五   | 数学    |    92 |    2 |
| 张三   | 数学    |    90 |    3 |
| 张三   | 语文    |    89 |    4 |
| 李四   | 语文    |    79 |    5 |
| 李四   | 数学    |    76 |    6 |
+--------+---------+-------+------+

该查询按照分数由高到低为所有行分配了排名。

按多列分组排名

此实例演示了如何按照多列进行分组,并在每个组内进行排名。

SELECT
  name, subject, score,
  RANK() OVER (PARTITION BY subject ORDER BY score DESC) AS `rank`
FROM scores;

以下是该语句的输出:

+--------+---------+-------+------+
| name   | subject | score | rank |
+--------+---------+-------+------+
| 王五   | 数学    |    92 |    1 |
| 张三   | 数学    |    90 |    2 |
| 李四   | 数学    |    76 |    3 |
| 王五   | 语文    |    98 |    1 |
| 张三   | 语文    |    89 |    2 |
| 李四   | 语文    |    79 |    3 |
+--------+---------+-------+------+

该查询首先按 subject 列分组,然后在每个组内按 score 列降序排名。这样,语文和数学两个科目的排名就是独立的了。

相同值的行排名相同

此实例演示了如何处理相同值的行的排名问题。

DROP TABLE IF EXISTS scores2;
CREATE TABLE scores2 (
  name VARCHAR(10),
  score INT
);

INSERT INTO scores2 VALUES
  ('张三', 88),
  ('李四', 92),
  ('王五', 92),
  ('赵六', 80);

SELECT
  name, score,
  RANK() OVER (ORDER BY score DESC) AS `rank`
FROM scores2;

以下是该语句的输出:

+--------+-------+------+
| name   | score | rank |
+--------+-------+------+
| 李四   |    92 |    1 |
| 王五   |    92 |    1 |
| 张三   |    88 |    3 |
| 赵六   |    80 |    4 |
+--------+-------+------+

可以看到,李四和王五的分数都是 92,两人的排名都是 1。这是因为 RANK() 函数会为相同值的行分配相同的排名。

与 DENSE_RANK()函数的区别

RANK() 函数与 DENSE_RANK() 函数在处理相同值的行时有所不同。此实例演示了两个函数的区别。

SELECT
  name, score,
  RANK() OVER (ORDER BY score DESC) AS `rank`,
  DENSE_RANK() OVER (ORDER BY score DESC) AS `dense_rank`
FROM scores2;

以下是该语句的输出:

+--------+-------+------+------------+
| name   | score | rank | dense_rank |
+--------+-------+------+------------+
| 李四   |    92 |    1 |          1 |
| 王五   |    92 |    1 |          1 |
| 张三   |    88 |    3 |          2 |
| 赵六   |    80 |    4 |          3 |
+--------+-------+------+------------+

对于相同值的行,RANK() 函数会分配相同的排名,而 DENSE_RANK() 函数则会为下一个不同值的行分配下一个连续排名。

相关函数

  • MariaDB ROW_NUMBER() 函数也用于为分区内的行分配排名,但它不会为相同值的行分配相同的排名。
  • MariaDB DENSE_RANK() 函数与 RANK() 函数类似,但为相同值的行分配相同的紧凑排名。
  • MariaDB NTILE() 函数用于将分区内的行分配为若干桶。

结论

本文介绍了 MariaDB RANK() 函数的语法、用法和实例。RANK() 函数是一个窗口函数,用于为分区内的行按指定的排序规则进行排名。它能够很好地处理相同值的行,为它们分配相同的排名。通过与 PARTITION BYORDER BY 子句的结合使用,RANK() 函数可以实现各种复杂的分组和排名需求。此外,将 RANK() 函数与其他窗口函数组合使用,可以支持更加丰富的数据分析场景。总的来说,RANK() 函数是 MariaDB 中处理排名和 TopN 分析的一个非常有用的工具。