zoukankan      html  css  js  c++  java
  • HIVE常用函数(1)聚合函数和序列函数

    SUM--
    sum(汇总字段) over (partition by 分组字段 order by 排序字段)

    如果不指定ROWS BETWEEN,默认为从起点到当前行;
    如果不指定ORDER BY,则将分组内所有值累加;
    关键是理解ROWS BETWEEN含义,也叫做WINDOW子句:
    PRECEDING:往前
    FOLLOWING:往后
    CURRENT ROW:当前行
    UNBOUNDED:起点,

      UNBOUNDED PRECEDING 表示从前面的起点,

      UNBOUNDED FOLLOWING:表示到后面的终点
    –其他AVG,MIN,MAX,和SUM用法一样。

    select 
       cookieid, 
       createtime, 
       pv, 
       sum(pv) over (partition by cookieid order by createtime rows between unbounded preceding and current row) as pv1, 
       sum(pv) over (partition by cookieid order by createtime) as pv2, 
       sum(pv) over (partition by cookieid) as pv3, 
       sum(pv) over (partition by cookieid order by createtime rows between 3 preceding and current row) as pv4, 
       sum(pv) over (partition by cookieid order by createtime rows between 3 preceding and 1 following) as pv5, 
       sum(pv) over (partition by cookieid order by createtime rows between current row and unbounded following) as pv6 
    from cookie1;

    pv1: 分组内从起点到当前行的pv累积,如,11号的pv1=10号的pv+11号的pv, 12号=10号+11号+12号
    pv2: 同pv1
    pv3: 分组内(cookie1)所有的pv累加
    pv4: 分组内当前行+往前3行,如,11号=10号+11号, 12号=10号+11号+12号, 13号=10号+11号+12号+13号, 14号=11号+12号+13号+14号
    pv5: 分组内当前行+往前3行+往后1行,如,14号=11号+12号+13号+14号+15号=5+7+3+2+4=21
    pv6: 分组内当前行+往后所有行,如,13号=13号+14号+15号+16号=3+2+4+4=13,14号=14号+15号+16号=2+4+4=10
    复制代码

    NTILE,ROW_NUMBER,RANK,DENSE_RANK

    NTILE(n)  用于将分组数据按照顺序切分成n片,返回当前切片
    NTILE不支持ROWS BETWEEN,比如 NTILE(2) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
    如果切片不均匀,默认增加第一个切片的分布

    例子:

    有下图的1000家店铺的价格数据。我们想知道,价格排名前30%的店铺的平均价格,和后70%的。

    思路:

    把店铺均匀的按价格递减顺序分成10片。然后取切片数=1,2,3的即为前30%。

    sql:

    复制代码
    -- 1 把记录按价格顺序拆分成10片
    drop table if exists test_dp_price_rk;
    create table test_dp_price_rk
    as
    select
     id,
     price,
     NTILE(10) OVER (order by price desc) as rn
    from test_dp_price;
    
    -- 2 按片取30%和70%,分别计算平均值
    select
      new_rn,
      max(case when new_rn=1 then 'avg_price_first_30%' when new_rn=2 then 'avg_price_last_70%' end) as avg_price_name,
      avg(price) avg_price
    from 
    (
      select 
        id,
        price,
        rn,
        case when rn in (1,2,3) then 1 else 2 end as new_rn
      from test_dp_price_rk
    )a
    group by new_rn;
    复制代码

    ROW_NUMBER()

    ROW_NUMBER() –从1开始,按照顺序,生成分组内记录的序列
    –比如,按照pv降序排列,生成分组内每天的pv名次
    ROW_NUMBER() 的应用场景非常多,再比如,获取分组内排序第一的记录;获取一个session中的第一条refer等。

    select row_number() over (partition by cookieid order by piv desc) as rn from table;

    —RANK() 生成数据项在分组中的排名,排名相等会在名次中留下空位    
    —DENSE_RANK() 生成数据项在分组中的排名,排名相等会在名次中不会留下空位

    select
      cookieid,
      createtime,
      pv,
      rank() over (partition by cookieid order by pv desc) as rn1,
      dense_rank() over (partition by cookieid order by pv desc) as rn2,
      row_number() over (partition by cookieid order by pv desc) as rn3
    from cookie.cookie2 
    where cookieid='cookie1';

    row_number: 按顺序编号,不留空位
    rank: 按顺序编号,相同的值编相同号,留空位
    dense_rank: 按顺序编号,相同的值编相同的号,不留空位

    CUME_DIST :小于等于当前值的行数/分组内总行数
    比如,统计小于等于当前薪水的人数,所占总人数的比例
    select 
      dept,
      userid,
      sal,
      cume_dist() over (order by sal) as rn1,
      cume_dist() over (partition by dept order by sal) as rn2
    from cookie.cookie3;

     –PERCENT_RANK :分组内当前行的RANK值-1/分组内总行数-1

      由于Hive 中的ORDER BY 对于大数据集 存在性能问题,

        延伸出了部分排序,以及将按相同KEY 控制到同一划分集合的需求。

        即以下两个方案 SORT BY , DISTRIBUTE BY, 我们分别对这两个方案进行介绍。

    sort by

     SORT BY 是一个部分排序方案, 其只会在每个reducer 中对数据进行排序,

    也就是执行一个局部排序过程。

    使用sort by 你可以指定执行的reduce 个数 (set mapred.reduce.tasks=<number>),

     

    对输出的数据再执行归并排序,即可以得到全部结果。

    distribute by 

    DISTRIBUTE BY 控制map 中的输出在 reducer 中是如何进行划分的。

    使用DISTRIBUTE BY 可以保证相同KEY的记录被划分到一个Reduce 中。

    cluster by    当sort by  和 distribute by  用到同一个字段 时 用  cluster by 代替







    使用sort by 你可以指定执行的reduce 个数 (set mapred.reduce.tasks=<number>),

     

    对输出的数据再执行归并排序,即可以得到全部结果。

  • 相关阅读:
    【Android Developers Training】 62. 搭建一个OpenGL ES环境
    【Android Developers Training】 61. 序言:使用OpenGL ES显示图像
    CentOS上安装mongodb
    Ubuntu 10.04上安装MongoDB
    linux awk 内置函数详细介绍(实例)
    无法import的原因(ImportError: No module named *****)
    C语言中volatile关键字的作用[转]
    数据对齐 posix_memalign 函数详解
    android ndk中使用gprof
    宽字符与窄字符
  • 原文地址:https://www.cnblogs.com/dll102/p/12093336.html
Copyright © 2011-2022 走看看