MySQL RANK 函数
简介:在本教程中,您将了解MySQL
RANK()
函数以及如何应用它以将排名分配给结果集的分区中的每一行。
MySQL RANK() 函数简介
RANK()
函数为结果集的分区中的每一行分配一个排名。行的等级由一加上前面的等级数指定。
以下显示了RANK()
函数的语法:
RANK() OVER ( PARTITION BY <expression>[{,<expression>...}] ORDER BY <expression> [ASC|DESC], [{,<expression>...}] )在这个语法中:
- 首先,
PARTITION BY
子句将结果集划分为分区。RANK()
功能在分区内执行,并在跨越分区边界时重新初始化。 - 其次,
ORDER BY
子句按一个或多个列或表达式对分区内的行进行排序。
ROW_NUMBER()
函数不同,RANK()
函数并不总是返回连续的整数。
假设我们有一个样本表如下:
CREATE TABLE rankDemo ( val INT ); INSERT INTO rankDemo(val) VALUES(1),(2),(2),(3),(4),(4),(5); SELECT * FROM rankDemo;
+------+ | val | +------+ | 1 | | 2 | | 2 | | 3 | | 4 | | 4 | | 5 | +------+ 7 rows in set (0.01 sec)以下语句使用
RANK()
函数为rankDemo
表中结果集的每一行分配一个排名:
SELECT val, RANK() OVER ( ORDER BY val ) my_rank FROM rankDemo;这是输出:
+------+---------+ | val | my_rank | +------+---------+ | 1 | 1 | | 2 | 2 | | 2 | 2 | | 3 | 4 | | 4 | 5 | | 4 | 5 | | 5 | 7 | +------+---------+ 7 rows in set (0.02 sec)如您所见,第二行和第三行具有相同的关系,因此它们获得相同的等级2。 第四行具有等级4,因为
RANK()
功能跳过等级3。
MySQL RANK() 函数示例
让我们使用sales
我们在窗口函数教程中创建的表进行演示。
以下是sales
表:
+----------------+-------------+--------+ | sales_employee | fiscal_year | sale | +----------------+-------------+--------+ | Alice | 2016 | 150.00 | | Alice | 2017 | 100.00 | | Alice | 2018 | 200.00 | | Bob | 2016 | 100.00 | | Bob | 2017 | 150.00 | | Bob | 2018 | 200.00 | | John | 2016 | 200.00 | | John | 2017 | 150.00 | | John | 2018 | 250.00 | +----------------+-------------+--------+ 9 rows in set (0.01 sec)以下声明使用
RANK()
功能按销售额按每年的销售额排名:
SELECT sales_employee, fiscal_year, sale, RANK( ) OVER ( PARTITION BY fiscal_year ORDER BY sale DESC ) sales_rank FROM sales;输出结果:
+----------------+-------------+--------+------------+ | sales_employee | fiscal_year | sale | sales_rank | +----------------+-------------+--------+------------+ | John | 2016 | 200.00 | 1 | | Alice | 2016 | 150.00 | 2 | | Bob | 2016 | 100.00 | 3 | | Bob | 2017 | 150.00 | 1 | | John | 2017 | 150.00 | 1 | | Alice | 2017 | 100.00 | 3 | | John | 2018 | 250.00 | 1 | | Alice | 2018 | 200.00 | 2 | | Bob | 2018 | 200.00 | 2 | +----------------+-------------+--------+------------+ 9 rows in set (0.01 sec)在这个例子中:
- 首先,
PARTITION BY
子句按财务年度将结果集分成多个分区。 - 然后,
ORDER BY
子句按销售额按降序对销售员工进行排序。
MySQL RANK函数与CTE示例
以下语句使用RANK()
函数查找每年最高的三个最高价值订单:
WITH order_values AS( SELECT orderNumber, YEAR(orderDate) order_year, quantityOrdered*priceEach AS order_value, RANK() OVER ( PARTITION BY YEAR(orderDate) ORDER BY quantityOrdered*priceEach DESC ) order_value_rank FROM orders INNER JOIN orderDetails USING (orderNumber) ) SELECT * FROM order_values WHERE order_value_rank <=3;这是输出:
+-------------+------------+-------------+------------------+ | orderNumber | order_year | order_value | order_value_rank | +-------------+------------+-------------+------------------+ | 10196 | 2013 | 9571.08 | 1 | | 10206 | 2013 | 9568.73 | 2 | | 10201 | 2013 | 9394.28 | 3 | | 10312 | 2014 | 10286.40 | 1 | | 10348 | 2014 | 9974.40 | 2 | | 10304 | 2014 | 9467.68 | 3 | | 10403 | 2015 | 11503.14 | 1 | | 10405 | 2015 | 11170.52 | 2 | | 10407 | 2015 | 10723.60 | 3 | +-------------+------------+-------------+------------------+ 9 rows in set (0.04 sec)在这个例子中:
- 首先,我们使用公用表表达式(CTE)来获取订单号,订单年份和排名。为了按照每年的订单价值对订单进行排名,我们使用按
RANK()
行年划分行的功能,并按降序对订单值进行排序。 - 然后,我们只选择排名小于或等于3的订单。
RANK()
函数为结果集中的每一行分配排名。