• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    总结几种MySQL中常见的排名问题

    前言:

    在某些应用场景中,我们经常会遇到一些排名的问题,比如按成绩或年龄排名。排名也有多种排名方式,如直接排名、分组排名,排名有间隔或排名无间隔等等,这篇文章将总结几种MySQL中常见的排名问题。

    创建测试表

    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);
    
    # 查看下插入的数据
    mysql> 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.普通排名

    按分数高低直接排名,从1开始,往下排,类似于row number。下面我们给出查询语句及排名结果。

    # 查询语句
    SELECT xuehao, score, @curRank := @curRank + 1 AS rank
    FROM scores_tb, (
    SELECT @curRank := 0
    ) r
    ORDER BY score desc;
    
    # 排序结果
    +--------+-------+------+
    | 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 |
    +--------+-------+------+

    上述查询语句中,我们申明了一个变量 @curRank ,并将此变量初始化为0,查得一行将此变量加一,并以此作为排名。我们看到这类排名是没间隔的并且有些分数相同但排名不同。

    2.分数相同,名次相同,排名无间隔

    # 查询语句
    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) r
    ORDER BY score desc;
    
    # 排名结果
    +--------+-------+------+
    | 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.并列排名,排名有间隔

    另外一种排名方式是相同的值排名相同,相同值的下一个名次应该是跳跃整数值,即排名有间隔。

    # 查询语句
    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
    ) r
    ORDER BY score desc) s;
    # 排名结果
    +--------+-------+------+
    | 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 |
    +--------+-------+------+

    上面介绍了三种排名方式,实现起来还是比较复杂的。好在MySQL8.0增加了窗口函数,使用内置函数可以轻松实现上述排名。

    MySQL8.0 利用窗口函数实现排名

    MySQL8.0中可以利用 ROW_NUMBER(),DENSE_RANK(),RANK() 三个窗口函数实现上述三种排名,需要注意的一点是as后的别名,千万不要与前面的函数名重名,否则会报错,下面给出这三种函数实现排名的案例:

    # 三条语句对于上面三种排名
    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;
    
    # 一条语句也可以查询出不同排名
    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);
    
    # 排名结果
    +--------+-------+-------+---------+---+
    | 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 |
    +--------+-------+-------+---------+---+

    总结:

    本文给出三种不同场景下实现统计排名的SQL,可以根据不同业务需求选取合适的排名方案。对比MySQL8.0,发现利用窗口函数可以更轻松实现排名,其实业务需求远远比我们举的示例要复杂许多,用SQL实现此类业务需求还是需要慢慢积累的。

    以上就是总结几种MySQL中常见的排名问题的详细内容,更多关于MySQL 排名的资料请关注脚本之家其它相关文章!

    您可能感兴趣的文章:
    • MYSQL实现排名及查询指定用户排名功能(并列排名功能)实例代码
    • Mysql排序获取排名的实例代码
    • MySQL页面访问统计及排名情况
    • MySQL中给自定义的字段查询结果添加排名的方法
    • mysql分组取每组前几条记录(排名) 附group by与order by的研究
    上一篇:浅谈MySQL8.0 异步复制的三种方式
    下一篇:深入分析MySQL数据类型 DECIMAL
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    总结几种MySQL中常见的排名问题 总结,几种,MySQL,中,常见,