• Hive分析窗口函数


      Hive中提供了越来越多的分析函数,用于完成负责的统计分析。

      今天简单整理一下,以务以后自己快速查询,也给看到的朋友作个参考。

      分析函数主要用于实现分组内所有和连续累积的统计。

    一. AVG,MIN,MAX,和SUM

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

    二. NTILE,ROW_NUMBER,RANK,DENSE_RANK

      1) NTILE

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

      2)ROW_NUMBER

      ROW_NUMBER() –从1开始,按照顺序,生成分组内记录的序列,比如,按照pv降序排列,生成分组内每天的pv名次。

      ROW_NUMBER() 的应用场景非常多,再比如,获取分组内排序第一的记录;获取一个session中的第一条refer等。

      3)RANK和DENSE_RANK

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

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

    三. CUME_DIST,PERCENT_RANK

      1) CUME_DIST

      CUME_DIST 小于等于当前值的行数/分组内总行数
      比如,统计小于等于当前薪水的人数,所占总人数的比例

      2) PERCENT_RANK

      将当前行的值归一化为0到1的值,其中全部(或者分组)的最大值对应1,最小值对应0,其他均匀分布在0到1之间。

    四. LAG,LEAD,FIRST_VALUE,LAST_VALUE

      1)LAG

      LAG(col,n,DEFAULT) 用于统计窗口内往上第n行值
      第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往上第n行为NULL时候,取默认值,如不指定,则为NULL)

      2)LEAD

      与LAG相反
      LEAD(col,n,DEFAULT) 用于统计窗口内往下第n行值
      第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为NULL时候,取默认值,如不指定,则为NULL)

      3)FIRST_VALUE

      取分组内排序后,截止到当前行,第一个值,(如果不指定分组,则返回第一行的值)

      4)LAST_VALUE

      取分组内排序后,截止到当前行,最后一个值

      如果不指定ORDER BY,则默认按照记录在文件中的偏移量进行排序,会出现错误的结果

      如果想要取分组内排序后最后一个值,则需要变通一下,用FIRST_VALUE函数,然后按指定的排序字段倒排

    五. GROUPING SETS,GROUPING_ID,CUBE,ROLLUP

      这几个分析函数通常用于OLAP中,不能累加,而且需要根据不同维度上钻和下钻的指标统计,比如,分小时、天、月的UV数。

      1)GROUPING SETS

      在一个GROUP BY查询中,根据不同的维度组合进行聚合,等价于将不同维度的GROUP BY结果集进行UNION ALL

    SELECT 
    month,
    day,
    COUNT(DISTINCT cookieid) AS uv,
    GROUPING__ID 
    FROM lxw1234 
    GROUP BY month,day 
    GROUPING SETS (month,day,(month,day)) 
    ORDER BY GROUPING__ID;
     
    month         day             uv      GROUPING__ID
    ------------------------------------------------
    2015-03       NULL            5       1
    2015-04       NULL            6       1
    NULL          2015-03-10      4       2
    NULL          2015-03-12      1       2
    NULL          2015-04-12      2       2
    NULL          2015-04-13      3       2
    NULL          2015-04-15      2       2
    NULL          2015-04-16      2       2
    2015-03       2015-03-10      4       3
    2015-03       2015-03-12      1       3
    2015-04       2015-04-12      2       3
    2015-04       2015-04-13      3       3
    2015-04       2015-04-15      2       3
    2015-04       2015-04-16      2       3
     
     
    等价于
    SELECT month,NULL,COUNT(DISTINCT cookieid) AS uv,1 AS GROUPING__ID FROM lxw1234 GROUP BY month 
    UNION ALL 
    SELECT NULL,day,COUNT(DISTINCT cookieid) AS uv,2 AS GROUPING__ID FROM lxw1234 GROUP BY day
    UNION ALL 
    SELECT month,day,COUNT(DISTINCT cookieid) AS uv,3 AS GROUPING__ID FROM lxw1234 GROUP BY month,day

      2)GROUPING__ID

      其中的 GROUPING__ID,表示结果属于哪一个分组集合

      3)CUBE

      根据GROUP BY的维度的所有组合进行聚合。

    SELECT 
    month,
    day,
    COUNT(DISTINCT cookieid) AS uv,
    GROUPING__ID 
    FROM lxw1234 
    GROUP BY month,day 
    WITH CUBE 
    ORDER BY GROUPING__ID;
     
     
    month                  day             uv     GROUPING__ID
    --------------------------------------------
    NULL            NULL            7       0
    2015-03         NULL            5       1
    2015-04         NULL            6       1
    NULL            2015-04-12      2       2
    NULL            2015-04-13      3       2
    NULL            2015-04-15      2       2
    NULL            2015-04-16      2       2
    NULL            2015-03-10      4       2
    NULL            2015-03-12      1       2
    2015-03         2015-03-10      4       3
    2015-03         2015-03-12      1       3
    2015-04         2015-04-16      2       3
    2015-04         2015-04-12      2       3
    2015-04         2015-04-13      3       3
    2015-04         2015-04-15      2       3
     
     
     
    等价于
    SELECT NULL,NULL,COUNT(DISTINCT cookieid) AS uv,0 AS GROUPING__ID FROM lxw1234
    UNION ALL 
    SELECT month,NULL,COUNT(DISTINCT cookieid) AS uv,1 AS GROUPING__ID FROM lxw1234 GROUP BY month 
    UNION ALL 
    SELECT NULL,day,COUNT(DISTINCT cookieid) AS uv,2 AS GROUPING__ID FROM lxw1234 GROUP BY day
    UNION ALL 
    SELECT month,day,COUNT(DISTINCT cookieid) AS uv,3 AS GROUPING__ID FROM lxw1234 GROUP BY month,day

      4)ROLLUP

      是CUBE的子集,以最左侧的维度为主,从该维度进行层级聚合。

    比如,以month维度进行层级聚合:
    SELECT 
    month,
    day,
    COUNT(DISTINCT cookieid) AS uv,
    GROUPING__ID  
    FROM lxw1234 
    GROUP BY month,day
    WITH ROLLUP 
    ORDER BY GROUPING__ID;
     
    month                  day             uv     GROUPING__ID
    ---------------------------------------------------
    NULL             NULL            7       0
    2015-03          NULL            5       1
    2015-04          NULL            6       1
    2015-03          2015-03-10      4       3
    2015-03          2015-03-12      1       3
    2015-04          2015-04-12      2       3
    2015-04          2015-04-13      3       3
    2015-04          2015-04-15      2       3
    2015-04          2015-04-16      2       3
     
    可以实现这样的上钻过程:
    月天的UV->月的UV->总UV
    --把month和day调换顺序,则以day维度进行层级聚合:
     
    SELECT 
    day,
    month,
    COUNT(DISTINCT cookieid) AS uv,
    GROUPING__ID  
    FROM lxw1234 
    GROUP BY day,month 
    WITH ROLLUP 
    ORDER BY GROUPING__ID;
     
     
    day                    month              uv     GROUPING__ID
    -------------------------------------------------------
    NULL            NULL               7       0
    2015-04-13      NULL               3       1
    2015-03-12      NULL               1       1
    2015-04-15      NULL               2       1
    2015-03-10      NULL               4       1
    2015-04-16      NULL               2       1
    2015-04-12      NULL               2       1
    2015-04-12      2015-04            2       3
    2015-03-10      2015-03            4       3
    2015-03-12      2015-03            1       3
    2015-04-13      2015-04            3       3
    2015-04-15      2015-04            2       3
    2015-04-16      2015-04            2       3
     
    可以实现这样的上钻过程:
    天月的UV->天的UV->总UV
    (这里,根据天和月进行聚合,和根据天聚合结果一样,因为有父子关系,如果是其他维度组合的话,就会不一样)
  • 相关阅读:
    Mysql的select加锁分析
    浅析Kubernetes的工作原理
    HTTP/2部署使用
    Amazon新一代云端关系数据库Aurora
    为什么 kubernetes 天然适合微服务
    深入解读Service Mesh背后的技术细节
    微服务的接入层设计与动静资源隔离
    Prim算法和Kruskal算法介绍
    DAG及拓扑排序
    BFS和DFS
  • 原文地址:https://www.cnblogs.com/swg1124/p/7089683.html
Copyright © 2020-2023  润新知