Hive-Sql分析函数汇总

目录

  0 引 言

  1. 聚合分析函数

  2.排名分析函数

  3.数学分析函数

  4.行偏移量分析函数

  5.多维分析函数


 0 引 言

   分析函数在sql中非常重要,对于sqlboy来说是必须要掌握的 ,本文对Hive-Sql分析函数进行汇总和总结,Hive-Sql分析函数主要有以下五类:

  • 聚合分析函数
  • 排名分析函数
  • 数学分析函数
  • 行偏移量分析函数
  • 多维分析函数

其思维导图如下所示:

Hive-Sql分析函数汇总_第1张图片

 1. 聚合分析函数

  •         sum 求和
  •        count 统计记录数
  •        min 求最小值
  •        max 求最大值
  •        avg 求均值

具体案例参考链接: https://blog.csdn.net/godlovedaniel/article/details/104977785#6%20%E7%AA%97%E5%8F%A3%E5%87%BD%E6%95%B0

Hive-Sql分析函数汇总_第2张图片

  2.排名分析函数

  •        ROW_NUMBER  正常排序(行号)[1,2,3,4] -- 必须有order_by。适合于生成主键,连续序列或者不并列排名
  •        RANK  跳跃排序[1,2,2,4] -- 必须有order_by
  •       DENSE_RANK 密集排序/等位排序[1,2,2,3] -- 必须有order_by
  •       FIRST 从DENSE_RANK返回的集合中取出排在最前面的一个值的行
  •       LAST 从DENSE_RANK返回的集合中取出排在最后面的一个值的行
  •       FIRST_VALUE 返回窗口中第一行某字段值,取分组内排序后,截止到当前行,第一行某字段值
  •      LAST_VALUE 返回窗口中的最后一行某字段值,取分组内排序后,截止到当前行,最后一行某字段值

具体案例参考链接: https://blog.csdn.net/godlovedaniel/article/details/104977785#6%20%E7%AA%97%E5%8F%A3%E5%87%BD%E6%95%B0

Hive-Sql分析函数汇总_第3张图片

  3.数学分析函数 

  •       NTILE 用于将分组数据按照顺序切分成n片(n桶),返回当前切片值(桶序号).切片值就是桶的序号。类似于hive中分桶,用于求百分比
对于一组数字(1,2,3,4,5,6),ntile(2)切片后为(1,1,1,2,2,2)

(1,2,3,4,5,6,7),ntile(2)切片后为(1,1,1,1,2,2,2)

其序号的标定类似于hive中分桶的原理。
又叫分桶函数或分片函数。ntile(n),n表示分桶或分片的个数。
  •      COVAR_POP 返回一对表达式的总体协方差
  •      COVAR_SAMP 返回一对表达式的样本协方差
  •      CUME_DIST 计算一行在组中的相对位置。小于等于当前值的行数/分组内总行数
  •      PERCENT_RANK 分组内当前行的RANK值-1/分组内总行数-1
  •      PERCENTILE_DISC  返回一个与输入的分布百分比值相对应的数据值

    举例如下:

数据准备:

d1,user1,1000
d1,user2,2000
d1,user3,3000
d2,user4,4000
d2,user5,5000
 
CREATE EXTERNAL TABLE lxw1234 (
dept STRING,
userid string,
sal INT
) ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ',' 
stored as textfile location '/tmp/lxw11/';
 
 
hive> select * from lxw1234;
OK
d1      user1   1000
d1      user2   2000
d1      user3   3000
d2      user4   4000
d2      user5   5000
CUME_DIST
–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 lxw1234;
 
dept    userid   sal   rn1       rn2 
-------------------------------------------
d1      user1   1000    0.2     0.3333333333333333
d1      user2   2000    0.4     0.6666666666666666
d1      user3   3000    0.6     1.0
d2      user4   4000    0.8     0.5
d2      user5   5000    1.0     1.0
 
rn1: 没有partition,所有数据均为1组,总行数为5,
     第一行:小于等于1000的行数为1,因此,1/5=0.2
     第三行:小于等于3000的行数为3,因此,3/5=0.6
rn2: 按照部门分组,dpet=d1的行数为3,
     第二行:小于等于2000的行数为2,因此,2/3=0.6666666666666666

SELECT 
dept,
userid,
sal,
PERCENT_RANK() OVER(ORDER BY sal) AS rn1,   --分组内
RANK() OVER(ORDER BY sal) AS rn11,          --分组内RANK值
SUM(1) OVER(PARTITION BY NULL) AS rn12,     --分组内总行数
PERCENT_RANK() OVER(PARTITION BY dept ORDER BY sal) AS rn2 
FROM lxw1234;
 
dept    userid   sal    rn1    rn11     rn12    rn2
---------------------------------------------------
d1      user1   1000    0.0     1       5       0.0
d1      user2   2000    0.25    2       5       0.5
d1      user3   3000    0.5     3       5       1.0
d2      user4   4000    0.75    4       5       0.0
d2      user5   5000    1.0     5       5       1.0
 
rn1: rn1 = (rn11-1) / (rn12-1) 
	   第一行,(1-1)/(5-1)=0/4=0
	   第二行,(2-1)/(5-1)=1/4=0.25
	   第四行,(4-1)/(5-1)=3/4=0.75
rn2: 按照dept分组,
     dept=d1的总行数为3
     第一行,(1-1)/(3-1)=0
     第三行,(3-1)/(3-1)=1

4.不同行字段值比较分析函数(行偏移量分析函数)

  • LAG 可以访问结果集中的其它行而不用进行自连接。可以访问当前行之前的行,前偏移量函数,如果没有指定,偏移量默认为1
  • LEAD LEAD与LAG相反,LEAD可以访问当前行之后的行,后偏移量函数,用法同LAG函数

    *注:以上两个函数功能非常强大,使用较广 ,可以跨行取任意一个字段的值进行分析比较,采用上述函数避免了自连接操作,提高了效率。面试中也经常会被考察到,如求连续三天登录的用户等问题。

5.多维分析函数

  • GROUPING SETS 在一个GROUP BY查询中,根据不同的维度组合进行聚合,等价于将不同维度的GROUP BY结果集进行UNION ALL
  • GROUPING__ID 表示结果属于哪一个分组集合
  • CUBE 根据GROUP BY的维度的所有组合进行聚合
  • ROLLUP 是CUBE的子集,以最左侧的维度为主,从该维度进行层级聚合。
数据准备:

2015-03,2015-03-10,cookie1
2015-03,2015-03-10,cookie5
2015-03,2015-03-12,cookie7
2015-04,2015-04-12,cookie3
2015-04,2015-04-13,cookie2
2015-04,2015-04-13,cookie4
2015-04,2015-04-16,cookie4
2015-03,2015-03-10,cookie2
2015-03,2015-03-10,cookie3
2015-04,2015-04-12,cookie5
2015-04,2015-04-13,cookie6
2015-04,2015-04-15,cookie3
2015-04,2015-04-15,cookie2
2015-04,2015-04-16,cookie1
 
CREATE EXTERNAL TABLE lxw1234 (
month STRING,
day STRING, 
cookieid STRING 
) ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ',' 
stored as textfile location '/tmp/lxw11/';
 
 
hive> select * from lxw1234;
OK
2015-03 2015-03-10      cookie1
2015-03 2015-03-10      cookie5
2015-03 2015-03-12      cookie7
2015-04 2015-04-12      cookie3
2015-04 2015-04-13      cookie2
2015-04 2015-04-13      cookie4
2015-04 2015-04-16      cookie4
2015-03 2015-03-10      cookie2
2015-03 2015-03-10      cookie3
2015-04 2015-04-12      cookie5
2015-04 2015-04-13      cookie6
2015-04 2015-04-15      cookie3
2015-04 2015-04-15      cookie2
2015-04 2015-04-16      cookie1
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) 
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
 
 
等价于 
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
再如:

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
其中的 GROUPING__ID,表示结果属于哪一个分组集合。

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

是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
(这里,根据天和月进行聚合,和根据天聚合结果一样,因为有父子关系,如果是其他维度组合的话,就会不一样)
这种函数,需要结合实际场景和数据去使用和研究,只看说明的话,很难理解。

 

参考链接

http://lxw1234.com/archives/2015/04/193.htm

https://blog.csdn.net/dingchangxiu11/article/details/83145151?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-12.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-12.nonecase

你可能感兴趣的:(sql,hive)