title: MySQL 中使用变量实现排名名次
date: 2023-7-16 19:45:26
tags: - SQL 高级查询

一. 数据准备:

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

三. 只要数据有相同的排名就一样,排名依次排序(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

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

MySQL 中使用变量实现排名名次的更多相关文章

  1. 在MySQL中实现Rank高级排名函数【转】

    MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...

  2. 在MySQL中实现Rank高级排名函数

    MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...

  3. Mysql中的变量

    Mysql中的变量众多(即运行的配置),如:事务相关的.连接相关的.查询优化类的等等. 变量的作用域: 1.临时作用域 session级别:即打开一个与mysql server会话的基础上的作用域,变 ...

  4. MariaDB/MySQL中的变量

    在MySQL/MariaDB中有好几种变量类型:用户自定义变量.系统变量.一般的临时变量(即本地变量,或称为局部变量). 1.用户变量 用户变量是基于会话的,也是基于用户的,所以我觉得称之为会话变量更 ...

  5. MySql中的变量定义

    根据mysql手册,mysql的变量分为两种:系统变量和用户变量.但是在实际使用中,还会遇到诸如局部变量.会话变量等概念.根据个人感觉,mysql变量大体可以分为四种类型: 一.局部变量. 局部变量一 ...

  6. MySql中的变量定义(转)

    根据mysql手册,mysql的变量分为两种:系统变量和用户变量.但是在实际使用中,还会遇到诸如局部变量.会话变量等概念.根据个人感觉,mysql变量大体可以分为四种类型: 一.局部变量. 局部变量一 ...

  7. MYSQL 中的变量

    1.用户自己定义变量 2.系统变量(全局变量,会话变量) ----------------------------------------------------------------------- ...

  8. Node.js和mybatis分别实现mysql中like变量模糊查询

    <!-- mybatis --> <where> <if test="varName != '' and varName != null" > ...

  9. mysql查询语句中用户变量的使用

    先上代码吧 SELECT `notice`.`id` , `notice`.`fid` , `notice`.`has_read` , `notice`.`notice_time` , `notice ...

  10. MySQL中变量的使用

    一.认识MySQL 中的变量 在MySQL中变量的绝大部分的用处都是在存储过程和存储函数中. 当然也可以抛开存储过程和存储函数来单独使用. 变量在MySQL中的运用和在编程语言中的运用大体相同 二.M ...

随机推荐

  1. JS 判断域名并跳转到指定页面

    判断访问指定域名,进行页面跳转 <!DOCTYPE html> <html> <head> <title>正在玩命加载中--</title> ...

  2. PPT 商务PPT怎么做

    商务报告:公司专属PPT模板怎么做? 通过LOGO 提取主色调 搜集相关元素 通过LOGO 提取主色调 搜集相关元素 下载图片使用 建立版面

  3. Linux 查找进程所在目录

    查找进程所在目录位置 # 打出进程ID [root@iZuf64tp28136djioi3ki8Z /]# ps -ef|grep redis root 3451 1 0 Jun10 ? 07:02: ...

  4. GPT-4测评,大家先别急,图片输入还没来

    昨天GPT-4朋友圈刷屏,我更新了一篇小文章,极简罗列GPT-4的一些情报: 1 ChatGPT Plus用户才可试用GPT-4 2 试用阶段每四小时最多100条信息 3 知识库还是2021年 4 上 ...

  5. 【Django drf】序列化器总结

    目录 序列化器字段 外键字段自定义序列化 在模型类中写方法 在序列化类中写方法 反序列化 外键字段反序列化保存 ModelSerializer使用总结 序列化器字段 序列化中的字段可以根据用途分为三种 ...

  6. AnaConda 虚拟环境创建失败的解决方案

    问题:创建环境时,AnaConda界面下放一直显示正在创建中,然后过几分钟报错! 我的解决方法:--关闭 VPN... 其他解决方案请参考这篇文章:Here

  7. 【每日一题】23.Removal (计数DP)

    补题链接:Here 计数DP讲解:Here 这是一个计数类的dp dp[i][j]表示前i个数字中,删除j个元素的方案数 很容易得到转移方程:\(f[i][j] = f[i - 1][j - 1] + ...

  8. 极速生成缩略图,Serverless 支撑赛事转播锁定冬奥亮点

    作者 | 西流.筱姜 ​ "北京冬奥会在开赛的第四天便成为了历史上收视最高的一届冬奥会,其转播内容总生产量将达 6000 小时,超过平昌冬奥会的 5400 小时.关注北京冬奥会的人群比往届都 ...

  9. 七、java操作swift对象存储(动态大对象)

    系列导航 一.swift对象存储环境搭建 二.swift添加存储策略 三.swift大对象--动态大对象 四.swift大对象--静态态大对象 五.java操作swift对象存储(官网样例) 六.ja ...

  10. 从0开发3D引擎(十三):使用领域驱动设计,从最小3D程序中提炼引擎(第四部分)

    目录 上一篇博文 下一篇博文 本文流程 回顾上文 解释基本的操作 如何在浏览器上运行index.html 开始实现 准备 建立代码的文件夹结构,约定模块文件的命名规则 模块文件的命名原则 一级和二级文 ...