zoukankan      html  css  js  c++  java
  • hive笔记之row_number、rank、dense_rank

    hive中有三个与分组排序相关的分析函数(我起初也认为是窗口函数,后来看到手册里是把他们划到了Analytics functions下),row_number、rank、dense_rank,我一直傻傻的分不大清它们的区别,特地总结一下。

    现在模拟一个场景,有一个比较时髦的学校决定借助大数据技术来提高教学质量,其中就有一张表存放了全校每个学生的考试成绩,按照学期进行分区,创建这张表:

    create table t_score (
      class string,
      name string,
      score int
    ) partitioned by (term string);

    插入一些测试数据:

    -- 注意这里为了做实验方便使用insert...values的形式,会产生临时表
    insert into t_score partition (term="201702")
    values 
    ("一班", "小黑", 80),
    ("一班", "小白", 90),
    ("一班", "小赤", 100),
    ("二班", "小橙", 80),
    ("二班", "小红", 90),
    ("二班", "小绿", 100),
    ("三班", "小青", 90),
    ("三班", "小蓝", 100),
    ("三班", "小紫", 100);

    现在校长想知道在2017年下学期的考试中每个班级的排名情况:

    select *, rank() over (partition by class order by score desc) from t_score where term="201702";

    下面是查询结果:

    image 

    但是仔细看下查询结果,发现有些不对劲的地方,三班的排名出现了两个并列第一,然后紧接着就是第三名,没有第二名了,按照我们一般的想法,如果有并列的话那么后面的就会排名提前,dense_rank可以实现这个效果:

    select *, dense_rank() over (partition by class order by score desc) from t_score where term="201702";
    

    image

    跟预期一致,三班的两个并列第一,然后紧接着就是第二名。

    将rank()和dense_rank()的结果放在一起对比一下加深理解:

    image   image 

    dense,意思是稠密的,稠密意味着生成的排名序列中没有空隙(连续的),而rank()生成的排名序列中可能有空隙(可能是不连续的)。

    但是这时候校长不高兴了,他不喜欢这种并列的排名方式,他说要重新制定排名规则:

    1. 首先按照成绩排序
    2. 成绩相同的不要并列,而是再按照姓名排序,姓氏靠后的认倒霉吧
    3. 对于成绩和姓名都完全相同的情况,校长大人没有指定就假装不存在这种情况好啦
    

    没办法,校长最大,只能再改下我们的sql,因为rank在生成排名序列的时候都会出现并列的情况,稀的稠的都不行啊,所以不能采用rank这种方式了,不过没事我们还有招,有一个函数叫做row_number,它不考虑并列的情况,就是单纯的排序,按照顺序挨个的发号码:

    select *, row_number() over (partition by class order by score desc, name) from t_score where term="201702";

    效果大概是这样:

    image

    没有出现并列的情况,可以交差了。

    总结一下:

    rank / dense_rank / row_number的语法都是一样的,不同的只是几个特性:

    1. rank / dense_rank都考虑了并列的情况,所以序号可能不唯一,rank在出现并列之后会不连续,而dense_rank是连续的

    2. row_number不考虑并列的情况,所以序号是唯一的,并且也不会出现不连续

    .

  • 相关阅读:
    微信小程序踩坑(二)——微信小程序recorderManager和innerAudioContext相关
    log4j:WARN Please initialize the log4j system properly解决办法
    如何跳过登录验证码
    Fiddler Mock长度变化的response不成功
    解决Chrome浏览器访问https提示“您的连接不是私密连接”的问题
    Fiddler抓不到https的解决办法
    互联网项目流程
    测试人员参与线下问题处理须知
    Mac下安装证书fiddlerRoot.cer
    MySQL存储过程中实现执行动态SQL语句
  • 原文地址:https://www.cnblogs.com/cc11001100/p/8978279.html
Copyright © 2011-2022 走看看