MySQL: How to check out the top n records in each packet?

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_datethe 年、月, and order_amountperformed 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_monthAnd @order_rankis our custom variables.

Use :=dynamically create a variable without having to use setthe command.

Phrase meaning:

Get order_datethe month values, assigned to current_month, so that you can track each month.

Phrase meaning:

Compare current_monthand this record in a month, if the same, order_rankincrement 1 , otherwise set to 1 .

Note that , @current_monthin the @order_ranklatter, for example to perform this record:

ifDetermination, MONTH(order_date)a value of 2 , and current_montha 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个查询语句。

推荐阅读:

Guess you like

Origin www.cnblogs.com/yogoup/p/12157869.html