Preface: In some application scenarios, we often encounter some ranking problems, such as ranking by grades or age. There are many ways to rank, such as direct ranking, group ranking, ranking with intervals or ranking without intervals, etc. This article will summarize several common ranking problems in MySQL. Create a test table create table scores_tb ( id int auto_increment primary key, xuehao int not null, score int not null )ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into scores_tb (xuehao,score) values (1001,89),(1002,99),(1003,96),(1004,96),(1005,92),(1006,90),(1007,90),(1008,94); # View the inserted datamysql> select * from scores_tb; +----+--------+-------+ | id | xuehao | score | +----+--------+-------+ | 1 | 1001 | 89 | | 2 | 1002 | 99 | | 3 | 1003 | 96 | | 4 | 1004 | 96 | | 5 | 1005 | 92 | | 6 | 1006 | 90 | | 7 | 1007 | 90 | | 8 | 1008 | 94 | +----+--------+-------+ 1. Ordinary ranking Rank directly by score, starting from 1 and going down, similar to row number. Below we give the query statement and ranking results. # Query statement SELECT xuehao, score, @curRank := @curRank + 1 AS rank FROM scores_tb, ( SELECT @curRank := 0 ) ORDER BY score desc; # Sorting results +--------+-------+------+ | xuehao | score | rank | +--------+-------+------+ | 1002 | 99 | 1 | | 1003 | 96 | 2 | | 1004 | 96 | 3 | | 1008 | 94 | 4 | | 1005 | 92 | 5 | | 1006 | 90 | 6 | | 1007 | 90 | 7 | | 1001 | 89 | 8 | +--------+-------+------+ In the above query statement, we declare a variable @curRank and initialize it to 0. When a row is found, we increment the variable by 1 and use it as the ranking. We can see that there is no gap in this type of ranking and some have the same score but different rankings. 2. Same scores, same rankings, no gap in ranking # Query statement SELECT xuehao, score, CASE WHEN @prevRank = score THEN @curRank WHEN @prevRank := score THEN @curRank := @curRank + 1 END AS rank FROM scores_tb, (SELECT @curRank := 0, @prevRank := NULL) ORDER BY score desc; # Ranking results+--------+-------+------+ | xuehao | score | rank | +--------+-------+------+ | 1002 | 99 | 1 | | 1003 | 96 | 2 | | 1004 | 96 | 2 | | 1008 | 94 | 3 | | 1005 | 92 | 4 | | 1006 | 90 | 5 | | 1007 | 90 | 5 | | 1001 | 89 | 6 | +--------+-------+------+ 3. Tied rankings, with gaps in rankings Another ranking method is that the same value has the same ranking, and the next rank of the same value should be a jumping integer value, that is, there are gaps in the ranking. # Query statement SELECT xuehao, score, rank FROM (SELECT xuehao, score, @curRank := IF(@prevRank = score, @curRank, @incRank) AS rank, @incRank := @incRank + 1, @prevRank := score FROM scores_tb, ( SELECT @curRank := 0, @prevRank := NULL, @incRank := 1 ) ORDER BY score desc) s; # Ranking results+--------+-------+------+ | xuehao | score | rank | +--------+-------+------+ | 1002 | 99 | 1 | | 1003 | 96 | 2 | | 1004 | 96 | 2 | | 1008 | 94 | 4 | | 1005 | 92 | 5 | | 1006 | 90 | 6 | | 1007 | 90 | 6 | | 1001 | 89 | 8 | +--------+-------+------+ The three ranking methods introduced above are relatively complicated to implement. Fortunately, MySQL 8.0 has added window functions, and the above ranking can be easily achieved using built-in functions. MySQL 8.0 uses window functions to implement ranking In MySQL 8.0, you can use the three window functions ROW_NUMBER(), DENSE_RANK(), and RANK() to implement the above three rankings. One thing to note is that the alias after as must not be the same as the previous function name, otherwise an error will be reported. The following are examples of these three functions implementing rankings: # Three statements for the above three rankings select xuehao,score, ROW_NUMBER() OVER(order by score desc) as row_r from scores_tb; select xuehao,score, DENSE_RANK() OVER(order by score desc) as dense_r from scores_tb; select xuehao,score, RANK() over(order by score desc) as r from scores_tb; # One statement can also query different rankings SELECT xuehao,score, ROW_NUMBER() OVER w AS 'row_r', DENSE_RANK() OVER w AS 'dense_r', RANK() OVER w AS 'r' FROM `scores_tb` WINDOW w AS (ORDER BY `score` desc); # Ranking results+--------+-------+-------+---------+---+ | xuehao | score | row_r | dense_r | r | +--------+-------+-------+---------+---+ | 1002 | 99 | 1 | 1 | 1 | | 1003 | 96 | 2 | 2 | 2 | | 1004 | 96 | 3 | 2 | 2 | | 1008 | 94 | 4 | 3 | 4 | | 1005 | 92 | 5 | 4 | 5 | | 1006 | 90 | 6 | 5 | 6 | | 1007 | 90 | 7 | 5 | 6 | | 1001 | 89 | 8 | 6 | 8 | +--------+-------+-------+---------+---+ Summarize: This article provides SQL statements for implementing statistical ranking in three different scenarios. You can select the appropriate ranking solution based on different business needs. Compared with MySQL 8.0, we find that ranking can be achieved more easily by using window functions. In fact, business requirements are much more complicated than the examples we have given. It still takes time to accumulate experience to implement such business requirements using SQL. The above is a detailed summary of several common ranking issues in MySQL. For more information about MySQL ranking, please pay attention to other related articles on 123WORDPRESS.COM! You may also be interested in:
|
>>: Two ways to implement Vue users to log out to the login page without operation for a long time
Referring to the online information, I used cmake...
The load is generally estimated during system des...
Table of contents App Update Process Rough flow c...
The JavaScript hasOwnProperty() method is the pro...
<br />This problem does not exist in many sm...
js date time format Convert the date and time to ...
Nowadays, whether you are working on software or w...
Table of contents SQL execution order bin log Wha...
Table of contents Cause of the problem: Solution:...
Table of contents 1. Install the proxy module 2. ...
Use JS to implement object-oriented methods to ac...
The previous article introduced a detailed exampl...
Table of contents Create a table View the databas...
Scenario 1: To achieve a semi-transparent border:...
Here we only focus on the installation and use of...