MySQL 中使用变量实现排名名次

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 一. 数据准备:

一. 数据准备:

CREATE TABLE sql_rank (
  id INT ( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT,
  user_id INT ( 11 ) UNSIGNED NOT NULL,
  score TINYINT ( 3 ) UNSIGNED NOT NULL,
  add_time date NOT NULL,
  PRIMARY KEY ( id ) 
) ENGINE = INNODB CHARSET = latin1;
INSERT INTO sql_rank ( user_id, score, add_time )
VALUES
  ( 100, 50, '2016-05-01' ),
  ( 101, 30, '2016-05-01' ),
  ( 102, 20, '2016-05-01' ),
  ( 103, 60, '2016-05-01' ),
  ( 104, 80, '2016-05-01' ),
  ( 105, 50, '2016-05-01' ),
  ( 106, 70, '2016-05-01' ),
  ( 107, 85, '2016-05-01' ),
  (
    108,
  60,
  '2016-05-01');

二. 不管数据相同与否,排名依次排序(1,2,3,4,5,6,7,…)

思路: 将已经排序好的数据从第一条依次取出来,取一条就自增加一,实现从 1 到最后的一个排名

SELECT
  obj.user_id,
  obj.score,
  @rownum := @rownum + 1 AS rownum 
FROM
  ( SELECT user_id, score FROM sql_rank ORDER BY score DESC ) obj,
  ( SELECT @rownum := 0 ) r


2105804-20230716203301484-31991034.png

三. 只要数据有相同的排名就一样,排名依次排序(1,2,2,3,3,4,5,…)

思路: 当出现相同的数据时,排名保持不变,此时则需要再设置一个变量,用来记录上一条数据的值,跟当前数据的值进行对比,如果相同,则排名不变,不相同则排名自增加 1

SELECT
  obj.user_id,
  obj.score,
CASE
    WHEN @prerow = obj.score THEN
    @currank 
    WHEN @prerow := obj.score THEN
    @currank := @currank + 1 
    WHEN @prerow = 0 THEN
    @currow := @currank + 1 
  END AS currank 
FROM
  ( SELECT user_id, score FROM sql_rank ORDER BY score DESC ) obj,
  ( SELECT @currank := 0, @prerow := NULL ) r


让我们逐行解释:

  1. WHEN @prerow = obj.score THEN @currank: 这行代码检查前一行的分数是否与当前行的分数相同。如果相同,则将当前的排名(@currank)赋值给当前行的排名。
  2. WHEN @prerow := obj.score THEN @currank := @currank + 1: 这行代码首先将当前行的分数赋值给@prerow变量,然后将当前排名(@currank)加1。
  3. WHEN @prerow = 0 THEN @currow := @currank + 1: 这行代码检查前一行的分数是否为0。如果是,则将当前排名(@currank)加1,并将结果赋值给@currow变量。
  4. END AS currank: 这行代码将计算得到的排名赋值给一个名为currank的列。



四. 当出现相同的数据时,排名保持不变,但是保持不变的排名依旧会占用一个位置,也就是类似于(1,2,2,2,5)这种排名

思路: 当出现相同的数据时,排名保持不变,但是保持不变的排名依旧会占用一个位置,也就是类似于(1,2,2,2,5)这种排名就是属于中间的三个排名是一样的,但是第五个排名按照上面一种情况是(1,2,2,2,3),现在则是排名相同也会占据排名的位置

SELECT
  obj_new.user_id,
  obj_new.score,
  obj_new.rownum 
FROM
  (
  SELECT
    obj.user_id,
    obj.score,
    @curRank := @curRank + 1 AS num_tmp,
    @incrRank :=
  CASE
      WHEN @prevRecord = obj.score THEN
      @incrRank 
      WHEN @prevRecord := obj.score THEN
      @curRank 
    END AS rownum 
  FROM 
    ( SELECT user_id, score FROM `sql_rank` ORDER BY score DESC ) obj,
  ( SELECT @curRank := 0, @prevRecord := NULL, @incrRank := 0 ) r 
  ) obj_new


2105804-20230716204443086-1438873318.png

这时候就新增加了一个变量,用于记录上一条数据的分数了,只要当前数据分数跟上一条数据的分数比较,相同分数的排名就不变,不相同分数的排名就加一,并且更新变量的分数值为该条数据的分数,依次比较。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1天前
|
存储 SQL 关系型数据库
MySQL存储过程 if、case、while、loop、游标、变量、条件处理程序
MySQL存储过程 if、case、while、loop、游标、变量、条件处理程序
52 0
|
1天前
|
存储 关系型数据库 MySQL
认识MySQL数据库中用户自定义变量
认识MySQL数据库中用户自定义变量。
46 0
|
1天前
|
存储 SQL 关系型数据库
⑩⑤【DB】详解MySQL存储过程:变量、游标、存储函数、循环,判断语句、参数传递..
⑩⑤【DB】详解MySQL存储过程:变量、游标、存储函数、循环,判断语句、参数传递..
47 0
|
5月前
|
缓存 关系型数据库 MySQL
MySQL - 数据库中的系统变量和用户变量详解
MySQL - 数据库中的系统变量和用户变量详解
111 0
|
5月前
|
存储 SQL 关系型数据库
MySQL基础-变量/流程控制/游标/触发器
MySQL基础-变量/流程控制/游标/触发器
|
9月前
|
SQL 关系型数据库 MySQL
MySQL变量使用与介绍之为查询结果增加序号列和自定义序号列
SQL三:用户表(包含字段有:用户ID[自增]、姓名、性别、民族、出生日期、身份证号),无论查询条件如何,要求查询的结果显示一个行号列(即:第一行显示1,第二行显示2,第三行显示3,依此类推)
198 0
|
9月前
|
存储 关系型数据库 MySQL
|
10月前
|
存储 关系型数据库 MySQL
MySQL基础篇——存储过程和函数中的变量
MySQL基础篇——存储过程和函数中的变量
86 0
|
10月前
|
存储 SQL Oracle
MySQL数据库,从入门到精通:第十六篇——MySQL变量、流程控制和游标详解(三)
MySQL数据库,从入门到精通:第十六篇——MySQL变量、流程控制和游标详解
66 0
|
10月前
|
存储 SQL 关系型数据库
MySQL数据库,从入门到精通:第十六篇——MySQL变量、流程控制和游标详解(二)
MySQL数据库,从入门到精通:第十六篇——MySQL变量、流程控制和游标详解
57 0