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

MariaDB DENSE_RANK() 函数的作用是为一个分组内的每一行分配一个排名,根据一个或多个排序表达式的值进行排序。

发布于

MariaDB 是一个开源的关系型数据库管理系统,它是 MySQL 的一个分支。MariaDB 提供了许多用于处理分组和排序的函数,其中之一就是 DENSE_RANK() 函数。

DENSE_RANK() 函数的作用是为一个分组内的每一行分配一个排名,根据一个或多个排序表达式的值进行排序。它的返回值是一个整数,表示排名的序号。它与 RANK() 函数的区别在于,它不会跳过任何排名,即使有相同的值。

语法

DENSE_RANK() 函数的语法如下:

DENSE_RANK() OVER (
  [PARTITION BY partition_expression, ...]
  ORDER BY sort_expression [ASC | DESC], ...
)

其中,PARTITION BY 子句是可选的,用于指定分组的依据,可以是一个或多个表达式,用逗号分隔。如果省略,则将整个结果集视为一个分组。

ORDER BY 子句是必需的,用于指定排序的依据,可以是一个或多个表达式,用逗号分隔。每个表达式后可以跟 ASCDESC 来指定升序或降序,如果省略,则默认为升序。

实例

下面我们来看一些使用 DENSE_RANK() 函数的实例。

为整个结果集分配排名

假设我们有一个名为 scores 的表,存储了学生的成绩,如下所示:

CREATE TABLE scores (
  id INT PRIMARY KEY,
  name VARCHAR(20),
  score INT
);

INSERT INTO scores VALUES
(1, 'Alice', 85),
(2, 'Bob', 90),
(3, 'Charlie', 95),
(4, 'David', 80),
(5, 'Eve', 75);

我们可以使用 DENSE_RANK() 函数来为整个结果集分配排名,根据 score 列的值进行降序排序。例如:

SELECT id, name, score, DENSE_RANK() OVER (ORDER BY score DESC) AS rank FROM scores;

输出结果如下:

+------+---------+-------+------+
| id   | name    | score | rank |
+------+---------+-------+------+
|    3 | Charlie |    95 |    1 |
|    2 | Bob     |    90 |    2 |
|    1 | Alice   |    85 |    3 |
|    4 | David   |    80 |    4 |
|    5 | Eve     |    75 |    5 |
+------+---------+-------+------+

这说明 DENSE_RANK() 函数为每一行分配了一个排名,从 1 开始,根据 score 列的值从高到低进行排序。注意,没有任何排名被跳过,即使有相同的值。

为每个分组分配排名

假设我们有一个名为 sales 的表,存储了销售员的销售额,如下所示:

CREATE TABLE sales (
  id INT PRIMARY KEY,
  name VARCHAR(20),
  region VARCHAR(20),
  amount DECIMAL(10,2)
);

INSERT INTO sales VALUES
(1, 'Alice', 'North', 1000.00),
(2, 'Bob', 'South', 2000.00),
(3, 'Charlie', 'East', 3000.00),
(4, 'David', 'West', 4000.00),
(5, 'Eve', 'North', 1500.00),
(6, 'Frank', 'South', 2500.00),
(7, 'Grace', 'East', 3500.00),
(8, 'Henry', 'West', 4500.00);

我们可以使用 DENSE_RANK() 函数来为每个分组分配排名,根据 region 列进行分组,根据 amount 列的值进行降序排序。例如:

SELECT id, name, region, amount, DENSE_RANK() OVER (PARTITION BY region ORDER BY amount DESC) AS rank FROM sales;

输出结果如下:

+------+---------+--------+---------+------+
| id   | name    | region | amount  | rank |
+------+---------+--------+---------+------+
|    7 | Grace   | East   | 3500.00 |    1 |
|    3 | Charlie | East   | 3000.00 |    2 |
|    5 | Eve     | North  | 1500.00 |    1 |
|    1 | Alice   | North  | 1000.00 |    2 |
|    6 | Frank   | South  | 2500.00 |    1 |
|    2 | Bob     | South  | 2000.00 |    2 |
|    8 | Henry   | West   | 4500.00 |    1 |
|    4 | David   | West   | 4000.00 |    2 |
+------+---------+--------+---------+------+

这说明 DENSE_RANK() 函数为每个分组内的每一行分配了一个排名,从 1 开始,根据 amount 列的值从高到低进行排序。注意,每个分组内的排名是独立的,不会受到其他分组的影响。

相关函数

除了 DENSE_RANK() 函数外,MariaDB 还提供了一些其他的函数,用于处理分组和排序的问题。例如:

  • RANK() 函数:为一个分组内的每一行分配一个排名,根据一个或多个排序表达式的值进行排序。它的返回值是一个整数,表示排名的序号。它与 DENSE_RANK() 函数的区别在于,它会跳过相同值的排名,即使有相同的值。
  • ROW_NUMBER() 函数:为一个分组内的每一行分配一个序号,根据一个或多个排序表达式的值进行排序。它的返回值是一个整数,表示序号的序号。它与 DENSE_RANK() 函数的区别在于,它不会考虑相同值的情况,即使有相同的值,也会分配不同的序号。
  • NTILE() 函数:将一个分组内的每一行分配到一个指定数量的桶中,根据一个或多个排序表达式的值进行排序。它的返回值是一个整数,表示桶的序号。它与 DENSE_RANK() 函数的区别在于,它不会根据值的大小分配排名,而是根据行的数量平均分配到桶中。

结论

本文介绍了 MariaDB 的 DENSE_RANK() 函数的基础用法与实例。DENSE_RANK() 函数可以用来为一个分组内的每一行分配一个排名,根据一个或多个排序表达式的值进行排序。它的返回值是一个整数,表示排名的序号。它与 RANK() 函数的区别在于,它不会跳过任何排名,即使有相同的值。我们还介绍了一些与 DENSE_RANK() 函数相关的函数,用于处理分组和排序的问题。