zoukankan      html  css  js  c++  java
  • Hive窗口函数 row_number over()和sum() over()的使用详解

    row_number over()的使用:

    假如我们有这样一组数据,我们需要求出不同性别的年龄top2的人的信息。这个时候怎么做?
    可能我们会首先想到分组,但是分组只能值top1,怎么样能求出top2,top3呢?这时候我们想如果分组后能够按照年龄排序然后标出来序号就好了!

    id   age  name sex
    
    1,18,xiaoli,male
    2,19,wang,male
    3,22,liu,female
    4,16,dawei,male
    5,30,erbao,male
    6,26,xiao,female
    7,18,chengua,male
    

    下面就介绍一个非常有用的函数:row_number() over()他的作用就是分组排序加上序号标记
    比如以上求解不同性别的年龄top2,我们可以这样做:
    建表导入数据:

    create table rownumber(id string,age int,name string,sex string)
    row format delimited
    fields terminated by ',';
    load data local inpath '/root/mytest/rowover.dat' into table rownumber;
    

    select id,age,name,sex,
    row_number() over(partition by sex order by age desc) as rownumber
    from rownumber;
    


    我们可以清楚的看到 row_number() over(partition by sex order by age desc) as rownumber
    就相当于增加了一列序号,over()中partition by sex是按照sex分组,order by age desc按照年龄降序排序,然后row_number()在加上序号。

    select id,age,name,sex
    from
    (select id,age,name,sex,
    row_number() over(partition by sex order by age desc) as rownumber
    from rownumber ) temp
    where rownumber<3;
    


    这样就求出分组topn了,很方便!

    sum() over()的使用:

    有这样的数据:第一列name,第二列月份mon,第三列金额jine
    A,2015-01,5
    A,2015-01,15
    B,2015-01,5
    A,2015-01,8
    B,2015-01,25
    A,2015-01,5
    C,2015-01,10
    C,2015-01,20
    A,2015-02,4
    A,2015-02,6
    C,2015-02,30
    C,2015-02,10
    B,2015-02,10
    B,2015-02,5
    A,2015-03,14
    A,2015-03,6
    B,2015-03,20
    B,2015-03,25
    C,2015-03,10
    C,2015-03,20

    我们需要求出对于每个人的一个月的总额和累计到当前月的总额。
    传统方法非常的麻烦,具体思路是;先求出月总额表(name,mon,amount),然后讲月总额表自联结,在过滤当前月份后面的月份,最终在求和。
    使用sum() over()可以轻松给解决,sum()首先我们都知道是求和,加上over()就是针对某个窗口求和了,具体哪个窗口呢?
    具体实现:
    求出每月的总额 放到表中,先将数据加载到表中,在求月总额

    create table monsum(name string,mon string,jine string)
    row format delimited
    fields terminated by ',';
    load data local inpath '/root/mytest/sumreport.dat' into table monsum;
     
    --求出月总额
    create table monamount 
    as
    select name,mon,sum(jine) as amount
    from monsum
    group by name,mon;
    


    然后使用窗口函数求出累计当前月总额,

    select name,mon,amount,
    sum(amount) over(partition by name order by mon rows between unbounded preceding and current row) as account
    from monamount;
    


    sum(amount)的求和是针对后面over()窗口的求和,
    over中partition by name order by mon 针对name这一组按照月份排序,rows between unbounded preceding and current 限定了行是按照在当前行不限定的往前处理,通俗就是处理当前以及之前的所有行的sum,即3月时sum(amount)求的时123月的和,2月时sum(amount)求的是12月的和。unbounded意思无限的 preceding在之前的,current row当前行。

  • 相关阅读:
    implementaion bottle session with beaker
    [梦]20050802
    网站更新部署20100912
    Cherokee不值得推荐,你还是可以看一看
    最简单方法远程调试Python多进程子程序
    nginx相关的问题
    本地配置host解析的问题
    base target问题,
    在asp.net中自动合并小图片并使用css sprite显示出来
    html编辑器
  • 原文地址:https://www.cnblogs.com/sjkzy/p/15089708.html
Copyright © 2011-2022 走看看