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. Windows Service 服务中,不能访问挂载目录(网络映射盘)

    SpringBoot Windows 自启动 - 通过 Windows Service 服务实现 Windows Service 服务中,不能访问挂载目录(网络映射盘) 在Windows操作系统中,系 ...

  2. 无法停止服务、无法终止 PID 4100 的进程

    服务中无法停止服务. 先查出服务对应的进程 Microsoft Windows [版本 10.0.19043.1348] (c) Microsoft Corporation.保留所有权利. C:\Us ...

  3. python实现微信扫码支付

    import datetime import hashlib import time import json import random import string import requests f ...

  4. 【GO】Go语言介绍 Go开发环境搭建 第一个helloworld 变量命名规范 变量的定义和使用

    今日内容 1 Go语言介绍 #Go语言介绍 Go 即 Golang,是Google公司2009年11月正式对外公开的一门编程语言 Go是[静态 强类型]语言,是区别于解析型语言的编译型语言 静态:类型 ...

  5. 编译busybox错误汇总

     提示错误: arm-linux-gcc:Command not found PATH里有/usr/oca/arm/bin,但是make的时候,就是找不到 arm-linux-gcc   原因: ex ...

  6. chage详解:liunx账户密码过期时处理

    公司安装elasticSearcher7.10.2版本时提示账户密码过期,可以做以下的处理方式: 一.查看账户的使用情况 chage -l baikang [root@localhost ~]# ch ...

  7. Ubuntu Linux下的PDF阅读器推荐——Okular

    安装方法 在Ubuntu下直接使用sudo apt-get install okular即可,如果中间遇到依赖项的问题,可以通过运行sudo apt --fix-broken install来自动修复 ...

  8. CSS - 正确解决 float 高度坍塌的问题

    <!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta cha ...

  9. 百度网盘(百度云)SVIP超级会员共享账号每日更新(2024.01.02)

    一.百度网盘SVIP超级会员共享账号 可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答. 我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免 ...

  10. 【面试题精讲】Redis如何实现分布式锁

    首发博客地址 系列文章地址 Redis 可以使用分布式锁来实现多个进程或多个线程之间的并发控制,以确保在给定时间内只有一个进程或线程可以访问临界资源.以下是一种使用 Redis 实现分布式锁的常见方法 ...