Maison >base de données >tutoriel mysql >Comment utiliser les fonctions de fenêtre MySQL pour obtenir un classement dans la liste

Comment utiliser les fonctions de fenêtre MySQL pour obtenir un classement dans la liste

王林
王林avant
2023-05-26 10:09:28965parcourir

Tout d'abord, créez une table de test

create table praise_record(
    id bigint primary key auto_increment,
    name varchar(10),
    praise_num int
) ENGINE=InnoDB;

Ensuite, laissez chatGpt générer des données de test pour nous

INSERT INTO praise_record (name, praise_num) VALUES ('John', 5);
INSERT INTO praise_record (name, praise_num) VALUES ('Jane', 3);
INSERT INTO praise_record (name, praise_num) VALUES ('Bob', 10);
INSERT INTO praise_record (name, praise_num) VALUES ('Alice', 3);
INSERT INTO praise_record (name, praise_num) VALUES ('David', 7);
INSERT INTO praise_record (name, praise_num) VALUES ('oct', 7);

Ensuite, nous pouvons commencer à réaliser nos besoins : renvoyer la liste des likes et renvoyer le classement

rank()

Utilisez le Fonction Rank() pour renvoyer la liste des likes, Rank() over()

## 注意这里返回的rank字段要用反引号包起来
select name, praise_num, rank() over (order by praise_num desc) as `rank` from praise_record;
+-------+------------+------+
| name  | praise_num | rank |
+-------+------------+------+
| Bob   |         10 |    1 |
| David |          7 |    2 |
| oct   |          7 |    2 |
| John  |          5 |    4 |
| Jane  |          3 |    5 |
| Alice |          3 |    5 |
+-------+------------+------+

Lors de l'utilisation de la fonction Rank(), le même nombre de likes obtiendra le même classement, et le classement peut sauter Donc le classement final. ne sera pas continu

dense_rank()

Utilisez la fonction dense_rank() pour renvoyer la liste des likes, dense_rank() over()

 select name, praise_num, dense_rank() over (order by praise_num desc) as `rank` from praise_record;
 
 +-------+------------+------+
| name  | praise_num | rank |
+-------+------------+------+
| Bob   |         10 |    1 |
| David |          7 |    2 |
| oct   |          7 |    2 |
| John  |          5 |    3 |
| Jane  |          3 |    4 |
| Alice |          3 |    4 |
+-------+------------+------+

La même chose que la fonction Rank(), le même point Le nombre de likes renverra le même classement, mais le classement final renvoyé par dense_rank() est un classement continu

row_number()

row_number() la fonction renvoie la liste des likes, row_number() over()

 select name, praise_num, row_number() over (order by praise_num desc) as `rank` from praise_record;
 +-------+------------+------+
| name  | praise_num | rank |
+-------+------------+------+
| Bob   |         10 |    1 |
| David |          7 |    2 |
| oct   |          7 |    3 |
| John  |          5 |    4 |
| Jane  |          3 |    5 |
| Alice |          3 |    6 |
+-------+------------+------+

row_number Le ( ) peut être utilisée lorsque la liste renvoyée ne nécessite que des numéros de série. Les trois fonctions ci-dessus sont toutes nouvellement ajoutées à MySQL 8.0, nous pouvons donc les simuler et les implémenter sur d'anciennes versions telles que MySQL 5.7, et en apprendre davantage sur ces trois fenêtres via la fonction. Way.Le principe d'implémentation de la fonction

Implémentation de simulation de la fonction Rank()

select p1.name, p1.praise_num, count(p2.praise_num) + 1 as `rank` from praise_record p1
left join praise_record p2 on p1.praise_num < p2.praise_num
group by p1.name, p1.praise_num
order by `rank`;
+-------+------------+------+
| name  | praise_num | rank |
+-------+------------+------+
| Bob   |         10 |    1 |
| David |          7 |    2 |
| oct   |          7 |    2 |
| John  |          5 |    4 |
| Jane  |          3 |    5 |
| Alice |          3 |    5 |
+-------+------------+------+

Nous pouvons utiliser la méthode d'auto-jointure pour compter les enregistrements avec un score inférieur au score de la ligne actuelle, et enfin ajouter 1 au décompte. valeur comme classement de la ligne actuelle à simuler. L'implémentation de simulation de Rank()

dense_rank()

select p1.name, p1.praise_num, count(distinct p2.praise_num) + 1 as `dense_rank` from praise_record p1
left join praise_record p2 on p1.praise_num < p2.praise_num
group by p1.name, p1.praise_num
order by `dense_rank`;
+-------+------------+------------+
| name  | praise_num | dense_rank |
+-------+------------+------------+
| Bob   |         10 |          1 |
| oct   |          7 |          2 |
| David |          7 |          2 |
| John  |          5 |          3 |
| Jane  |          3 |          4 |
| Alice |          3 |          4 |
+-------+------------+------------+

dense_rank est similaire à Rank. La seule différence est que distinct est ajouté pour dédupliquer le nombre de likes. le classement renvoyé pour différents nombres de likes est Implémentation de simulation du

row_number

##使用自定义变量得先初始化
set @rowNum = 0;
select name, praise_num, @rowNum := @rowNum +1 as `row_number`  from praise_record order by praise_num desc ;
+-------+------------+------------+
| name  | praise_num | row_number |
+-------+------------+------------+
| Bob   |         10 |          1 |
| David |          7 |          2 |
| oct   |          7 |          3 |
| John  |          5 |          4 |
| Jane  |          3 |          5 |
| Alice |          3 |          6 |
+-------+------------+------------+

Nous pouvons utiliser une variable rowNum pour enregistrer le numéro de ligne. Les données rowNUm de chaque ligne sont +1, afin que nous puissions obtenir le numéro de séquence que nous avons. je veux

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer