暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【sql】分组排序详解

删库跑路小分队 2021-09-03
2114
 

热情洋溢的春天呐

 



不错过春天❤️

也不错过你❤️




天暖了要照顾好自己

衣服也还要穿厚点

看起来胖胖的

让别人怕怕的

🌈🌈🌈


我们这次刷的题是分组排序的几种方法

~~~


先养眼,再看题

❤️

今天还是小姐姐




0

Question

分组排序


解之前我们已经提到分组排序row_number()但分组排序的家族中并不止这一个,这次主要说

row_number()

rank()

dense_rank()

ntile()




1

Function

详解




首先这几个都是分组排序,但最主要的区别就是

如果两个分数相同,排名是否同列以及排名是否相同。 


但是这个方法仅在mysql8.0以后hive或其他数据库支持 





话不多说,直接上表


原始数据


id
score
1
90
2
100
3
80
4100
590



期望数据



id
score
row_
number

rankdense_
rank
ntile
2
100
1
1
11
4
100
211
1
1
90
3
3
2
2
5
90
43
22
3
80
55
3
3







从图中我们就可以发现

(不想看文字,下面有表总结)


row_number

如果并列但名次反而不相同,但是后续的名次是连续的

rank

如果并列则名次相同,但是后续的名次会不连续

dense_rank

如果并列则名次相同,但是后续的名次是连续的

ntile

如果并列则名次相同,后续的名次连续


我用下表来做个概述


方法
名次是否连续
名次是否并列
row_number
yes
no
rankno
yes
dense_rankyes
yes
ntile
yes
yes




row_number()


原理是先使用over子句中的排序语句对记录进行排序,然后再根据这个排序生成序号


    select 
    *,
    row_number() over (order by score desc) as rank
    from score;



    查询结果如下


    id
    scorerank
    2
    100
    1
    4
    100
    2
    1
    90
    3
    5
    90
    4
    3
    80
    5



    使用场景

    一般在工作中,常用分组排序做web程序的分页,然后我们指定查询范围。 



    rank()


    作用效果和row_number()方法类似

    但是支持并列排名,但排名名次可能不连续 



      select 
      *,
      rank() over (order by score desc) as rank
      from score;


      查询结果如下


      id
      score
      rank
      2100
      1
      4
      100
      1
      190
      3
      5
      90
      3
      3
      80
      5




      dense_rank()


      作用效果和rank()方法类似,

      不仅支持并列排名,而且排名也是连续的 


        select 
        *,
        dense_rank() over (order by score) as rank
        from score;


        查询结果如下



        id
        score
        rank
        2
        100
        1
        4
        100
        1
        1
        90
        2
        5
        90
        2
        380
        3




        ntile()


        ntile()函数是最好理解

        同时也是最不好理解的

        结果既能够和其他函数相似

        也能够有很大的区别。 


          select 
          *,
          ntile(3) over (order by score desc) as rank
          from score;


          查询结果如下


          id
          score
          rank
          2
          100
          1
          4
          100
          1
          190
          2
          590
          2
          3
          80
          3






          ntile函数的分桶依据:


          1. 每组的记录数不能大于它上一组的记录数,即编号小的桶放的记录数不能小于编号大的桶。也就是说,第1组中的记录数只能大于等于第2组及以后各组中的记录数。


          2. 所有组中的记录数要么都相同,要么从某一个记录较少的组(命名为X)开始后面所有组的记录数都与该组(X组)的记录数相同。也就是说,如果有个组,前三组的记录数都是9,而第四组的记录数是8,那么第五组和第六组的记录数也必须是8。 


          举个🌰


          如果是50条,那么就是

          1-10 : 第一组 (十条)

          11-20 : 第二组(十条)

          21-30 : 第三组(十条)

          31-40 : 第四组(十条)

          41-50 : 第五组(十条)


          如果是51条,那么就是

          1-11 : 第一组(十一条)

          12-21 : 第二组(十条)

          22-31 : 第三组(十条)

          32-41 : 第四组(十条)

          42-51 : 第五组(十条) 



          2

          Zongjie

          总结


          在使用分组排序函数的时候要注意以下三点:

          1. 排名函数必须要有over子句

          2. 排名函数必须要有order by的over子句

          3. 分组内从1开始排序 




          3

          Else

          题外话



          在此,根据分组排序暂时告一段落。


          如果小伙伴还有其他的想法或问题也欢迎在评论区留言

          让我们一起成长为老鸟,赚大钱!



          扫码关注我

          郭大熊的公众号

          个人博客 : www.guodaxiong.com


          如果不曾见过阳光,我本可以忍受黑暗

           Hi GuoDaXiong 



          我是狗子

          祝你幸福


          文章转载自删库跑路小分队,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论