Problem Description
demand:
Check out the monthly order_amount(订单金额)
ranking the first three records.
For example 2019-02
, the query result should be that 3:
Solution
MySQL 5.7 and MySQL 8.0 has a different approach.
1. MySQL 5.7
Let's write a query.
According to order_date
the 年、月
, and order_amount
performed in descending order.
Then, add a new column: order_amount
(this record in the ranking this month).
Results of the:
It can be seen, according to 年、月、订单金额
the sort, and also more than one order_rank
, showing the rankings this record amount of orders in the month.
SQL above in this section is more personal:
@current_month
And @order_rank
is our custom variables.
Use :=
dynamically create a variable without having to use set
the command.
Phrase meaning:
Get order_date
the month values, assigned to current_month
, so that you can track each month.
Phrase meaning:
Compare current_month
and this record in a month, if the same, order_rank
increment 1 , otherwise set to 1 .
Note that , @current_month
in the @order_rank
latter, for example to perform this record:
if
Determination, MONTH(order_date)
a value of 2 , and current_month
a value of 1 , or the set of records.
接下来,把上面的SQL语句作为一个子查询,然后使用一个 where
条件就可以轻松拿到每组的 top 3。
最终语句:
执行结果:
2. MySQL 8
MySQL 8 引入了一个 rank()
函数,可以更简便的实现排行的功能。
执行结果:
效果和 5.7 中的方法是一致的。
我们看下语句中的 rank()
方法:
PARTITION BY
是指定分区依据,这里是根据订单的年、月
进行分区。ORDER BY
指定了分区内的排序依据,这里是根据订单的年、月、金额
进行降序排列。
这样就会自动计算出排行数值。
需要注意的是,这个地方和 5.7 的方法不一样:
就是参与排序的几个值一样的时候,rank
值是一样的。
最终的SQL语句:
翻译整理自:
https://towardsdatascience.com/mysql-how-to-write-a-query-that-returns-the-top-records-in-a-group-12865695f436
如果您有兴趣实践一下,在公众号“性能与架构”中发送消息:200106,会回复实践笔记的下载地址,包含建表语句、测试数据、MySQL5.7和8.0的这2个查询语句。
推荐阅读: