本文主要使用实例对Hive内建的一些聚合函数、分析函数以及采样函数进行比较详细的讲解。

一、基本聚合函数

数据聚合是按照特定条件将数据整合并表达出来,以总结出更多的组信息。Hive包含内建的一些基本聚合函数,如MAX, MIN, AVG等等,同时也通过GROUPING SETS, ROLLUP, CUBE等函数支持更高级的聚合。Hive基本内建聚合函数通常与GROUP BY连用,默认情况下是对整个表进行操作。在使用GROUP BY时,除聚合函数外其他已选择列必须包含在GROUP BY子句中。

例:计算employee表中数据总条数

hive>

SELECT COUNT(*) FROM employee;

例:计算employee表中数据总条数,sex_age必须包含在GROUP BY的子句中,否则报错!

hive>

SELECT sex_age, count(*) AS row_cnt FROM employee GROUP BY sex_age;

那么有一个问题,如果我需要选择一行,但此时我不想对其进行GROUP BY那应该怎么办呢?这里有两个方法,一个是后面要讲到的使用分析函数,另一个就是使用COLLECT_SET函数,该函数将返回一个包含被GROUP BY排除的列的副本集合。

例:使用COLLECT_SET,其中的列不用进行GROUP BY

hive>

SELECT sex_age, count(*) AS row_cnt FROM employee GROUP BY sex_age;

注:聚合函数在同一个语句中可以组合使用,但是不能嵌套使用,即不能在一个聚合函数中套用另一个聚合函数!

例:组合使用AVG和COUNT

hive>

SELECT sex_age.sex, AVG(sex_age.age) AS avg_age, count(*) AS row_cnt FROM employee GROUP BY sex_age.sex;

例:聚合函数与CASE WHEN组合使用

hive>

SELECT SUM(CASE WHEN sex_age.sex='Male' THEN sex_age.age ELSE 0 END)/COUNT(CASE WHEN sex_age.sex='Male' THEN 1 ELSE NULL END) AS male_age_avg FROM employee;

例:聚合函数与COALESCE和IF组合使用。COALESCE(arg1, arg2, arg3...):遇到非null参数即返回改值

hive>

SELECT SUM(COALESCE(sex_age.age, 0)) AS age_sum, SUM(IF(sex_age.sex='Female',sex_age.age,0)) AS female_age_sum FROM employee;

例:嵌套聚合函数将会报错

hive>

SELECT AVG(COUNT(*)) AS row_cnt FROM employee;

例:聚合函数与DISTINCT关键词组合使用。DISTINCT: 去重

hive>

SELECT COUNT(DISTINCT sex_age.sex) AS sex_uni_cnt, COUNT(DISTINCT name) AS name_uni_cnt FROM employee;

注:如果COUNT和DISTINCT连用,Hive将忽略对reducer个数的设置(如:set mapred.reduce.tasks=20;), 仅会有一个reducer!此时reduce将成为瓶颈,这时我们可以使用子查询的方式解决该问题。

----------------- 对比 ----------------------

例:瓶颈问题

hive>

SELECT COUNT(DISTINCT sex_age.sex) AS sex_uni_cnt FROM employee;

例:子查询解决COUNT, DISTINCT瓶颈

hive>

SELECT COUNT(*) AS sex_uni_cnt FROM (SELECT DISTINCT sex_age.sex FROM employee) a;

注:子句必须有一个别名,否则会解析语句失败。

在Hive的聚合中,如果某个聚合列的值中有null,则包含该null的行将在聚合时被忽略。为了避免这种情况,可以使用COALESCE来将null替换为一个默认值。

例:

hive>

CREATE TABLE t AS SELECT * FROM (SELECT employee_id-99 AS val1, (employee_id-98) AS val2 FROM employee_hr WHERE employee_id<=101 UNION ALL SELECT null val1, 2 AS val2 FROM employee_hr WHERE employee_id=100) a;

例:

hive>

SELECT * FROM t;

例:val1=null将被忽略,但该行对应的其他非null值继续被聚合!

hive>

SELECT SUM(val1), SUM(val1 + val2) FROM t;

例:将值为null的使用COALESCE替换为0

hive>

SELECT SUM(COALESCE(val1, 0)), SUM(COALESCE(val1, 0)+val2) FROM t;

可以设置hive.map.aggr属性来控制map阶段的聚合,默认是false。如果设置为true,则将在map任务时进行first-level聚合,这将使得map有更好的性能,但会消耗更多内存。

二、高级聚合

高级聚合主要有以下几种情况:

1. GROUPING SETS

该关键字可以实现对同一个数据集的多重GROUP BY操作。事实上GROUPING SETS是多个GROUP BY进行UNION ALL操作的简单表达,它仅使用一个stage完成这些操作。GROUPING SETS的子句中如果包换()数据集,则表示整体聚合。

例:

hive>

SELECT name, work_place[0] AS main_place,

count(employee_id) AS emp_id_cnt

FROM employee_id

GROUP BY name, work_place[0]

GROUPING SETS((name, work_place[0]), name, work_place[0], ());

||

SELECT name, work_place[0] AS main_place,

count(employee_id) AS emp_id_cnt

FROM employee_id

GROUP BY name, work_place[0]

UNION ALL

SELECT name, NULL AS main_place, count(employee_id) AS emp_id_cnt

FROM employee_id

GROUP BY name

UNION ALL

SELECT NULL AS name, work_place[0] AS main_place,

count(employee_id) AS emp_id_cnt

FROM employee_id

GROUP BY work_place[0]

UNION ALL

SELECT NULL AS name, NULL AS main_place,

count(employee_id) AS emp_id_cnt

FROM employee_id;

然而GROUPING SETS目前还有未解决的问题,参考HIVE-6950https://issues.apache.org/jira/browse/HIVE-6950

例:

hive>

SELECT sex_age.sex, sex_age.age,

count(name) AS name_cnt

FROM employee

GROUP BY sex_age.sex, sex_age.age

GROUPING SETS((sex_age.sex, sex_age.age));

2. ROLLUP和CUBE

这两个关键字都是GROUP BY的高级实现。

对比于规定了n层聚合的GROUPING SETS,ROLLUP会创建n+1层聚合,在此n表示分组列的个数。

GROUP BY a, b, c WITH ROLLUP 等价于 GROUP BY a,b,c GROUPING SETS ((a,b,c),(a,b),(a),())

CUBE将会对分组列进行所有可能的组合聚合。如果为CUBE指定了n列,则将返回2^n个聚合组合。

GROUP BY a, b, c WITH ROLLUP 等价于 GROUP BY a,b,c GROUPING SETS ((a,b,c),(a,b),(b,c),(a,c),(a),(b),(c),())

三、聚合条件--HAVING

从Hive0.7.0开始HAVING被添加到Hive作为GROUP BY结果集的条件过滤。HAVING可以作为子句的替代。

例:

hive>

SELECT sex_age.age FROM employee GROUP BY sex_age.age HAVING count(*)<=1;

例:作用同上

hive>

SELECT a.age FROM (SELECT COUNT(*) AS cnt, sex_age.age FROM employee GROUP BY sex_age.age) a WHERE a.cnt<=1;

四、解析函数

解析函数是从Hive0.11.0开始被支持,用于扫描多行输入来计算输出值。常与OVER, PARTITION BY, ORDER BY等连用。由于解析函数的用法相对复杂,在此不作讲解,有兴趣的可以上网搜索相关文章进行学习。

五、采样

当数据集非常大的时候,我们需要找一个子集来加快数据分析。此时我们需要数据采集工具以获得需要的子集。在此可以使用三种方式获得采样数据:random sampling, bucket sampling, block sampling.

1. Random sampling

使用RAND()函数和LIMIT关键字来获取样例数据。使用DISTRIBUTE和SORT关键字来保证数据是随机分散到mapper和reducer的。ORDER BY RAND()语句可以获得同样的效果,但是性能没这么高。

--Syntax:

SELECT * FROM <Table_Name> DISTRIBUTE BY RAND() SORT BY RAND()  LIMIT <N rows to sample>;

2. Bucket table sampling

该方式是最佳化采样bucket表。RAND()函数也可以用来采样整行。如果采样列同时使用了CLUSTERED BY,使用TABLESAMPLE语句会更有效率。

--Syntax:

SELECT * FROM <Table_Name>  TABLESAMPLE(BUCKET <specified bucket number to sample> OUT OF <total number of buckets> ON [colname|RAND()]) table_alias;

例:

hive>

CREATE TABLE employee_id_buckets (

name string,

employee_id int,

work_place ARRAY<string>,

sex_age STRUCT<sex:string,age:int>,

skills_score MAP<string,int>,

depart_title MAP<string,ARRAY<string >>

)

CLUSTERED BY (employee_id) INTO 2 BUCKETS

ROW FORMAT DELIMITED

FIELDS TERMINATED BY '|'

COLLECTION ITEMS TERMINATED BY ','

MAP KEYS TERMINATED BY ':';

INSERT OVERWRITE TABLE employee_id_buckets SELECT * FROM employee_id;

SELECT name FROM employee_id_buckets TABLESAMPLE(BUCKET 1 OUT OF 2 ON rand()) a;

3. Block sampling

该方式允许Hive随机抽取N行数据,数据总量的百分比(n百分比)或N字节的数据。

--Syntax:

SELECT *  FROM <Table_Name> TABLESAMPLE(N PERCENT|ByteLengthLiteral|N ROWS) s;

--ByteLengggthLiteral:

--(Digit)+ ('b' | 'B' | 'k' | 'K' | 'm' | 'M' | 'g' | 'G')

例:按行抽样

hive>

SELECT name FROM employee_id_buckets TABLESAMPLE(4 ROWS) a;

例:按数据量百分比抽样

hive>

SELECT name FROM employee_id_buckets TABLESAMPLE(10 PERCENT) a;

注:此方法有待考证,在Hive0.11.0中将所有25条数据全取出来了,在Hive0.13.0中取出了其中的12条,但是都不符合要求!!

例:按数据大小采样

hive>

SELECT name FROM employee_id_buckets TABLESAMPLE(1M) a;

总结

聚合和抽样,特别是聚合函数,在大数据处理过程中是处理数据的主要方法。通过自由的条件限制以及聚合函数组合,基本能完成任意要求的数据处理或分组。本文仅仅是针对Hive进行了部分比较细致的讲解,关于像解析函数之类的使用比较复杂一点的处理方式需要进行更深一步的了解和运用。希望本文能提供到一定的帮助!本文来自于互联网

9.hive聚合函数,高级聚合,采样数据的更多相关文章

  1. SQL Server聚合函数与聚合开窗函数 (转载)

    以下面这个表的数据作为示例. 什么是聚合函数?聚合函数:聚合函数就是对一组值进行计算后返回单个值(即分组).聚合函数在计算时都会忽略空值(null).所有的聚合函数均为确定性函数.即任何时候使用一组相 ...

  2. SQL Server聚合函数与聚合开窗函数

    以下面这个表的数据作为示例. 什么是聚合函数? 聚合函数:聚合函数就是对一组值进行计算后返回单个值(即分组).聚合函数在计算时都会忽略空值(null). 所有的聚合函数均为确定性函数.即任何时候使用一 ...

  3. Flask聚合函数(基本聚合函数、分组聚合函数、去重聚合函数))

    Flask聚合函数 1.基本聚合函数(sun/count/max/min/avg) 使用聚合函数先导入:from sqlalchemy import func 使用方法: sun():func.sum ...

  4. HIVE常用函数(1)聚合函数和序列函数

    SUM--sum(汇总字段) over (partition by 分组字段 order by 排序字段) 如果不指定ROWS BETWEEN,默认为从起点到当前行;如果不指定ORDER BY,则将分 ...

  5. oracle数据库函数之============‘’分析函数和聚合函数‘’

    1分析函数 分析函数根据一组行来进行聚合计算,用于计算完成狙击的累积排名等,分析函数为每组记录返回多个行 rank_number() 查询结果按照次序排列,不存在并列和站位的情况,可以用于做Oracl ...

  6. 入门大数据---SparkSQL常用聚合函数

    一.简单聚合 1.1 数据准备 // 需要导入 spark sql 内置的函数包 import org.apache.spark.sql.functions._ val spark = SparkSe ...

  7. 可以这样去理解group by和聚合函数

    写在前面的话:用了好久group by,今天早上一觉醒来,突然感觉group by好陌生,总有个筋别不过来,为什么不能够select * from Table group by id,为什么一定不能是 ...

  8. 可以这样去理解group by和聚合函数(转)

    http://www.cnblogs.com/wuguanglei/p/4229938.html 写在前面的话:用了好久group by,今天早上一觉醒来,突然感觉group by好陌生,总有个筋别不 ...

  9. sql 学习之 group by 及 聚合函数

    1.在使用 GROUP BY 子句时,Select列表中的所有列必须是聚合列(SUM,MIN/MAX,AVG等)或是GROUP BY 子句中包括的列.同样,如果在SELECT 列表中使用聚合列,SEL ...

  10. Sql Server的艺术(三) SQL聚合函数的应用

    SQL提供的聚合函数有求和,最大值,最小值,平均值,计数函数等. 聚合函数及其功能: 函数名称 函数功能 SUM() 返回选取结果集中所有值的总和 MAX() 返回选取结果集中所有值的最大值 MIN( ...

随机推荐

  1. bzoj 1226 学校食堂Dining

    Written with StackEdit. Description 小\(F\) 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜 ...

  2. NOIP2013 DAY2题解

    DAY2 T1积木大赛 传送门 题目大意:每次可以选区间[l,r]加1,最少选几次,让每个位置有 它应有的高度. 题解:O(n)扫一遍就好了.后一个比前一个的高度低,那么前一个已经把它覆盖了, 如果高 ...

  3. 常用的文件数据类型mime

    有时在编程中会用到文件的类型,比如http的请求或相应header头信息,文件上传时自定义头信息等. ai application/postscript aif audio/x-aiff aifc a ...

  4. Spring按名称自动装配--byName

    在Spring中,“按名称自动装配”是指,如果一个bean的名称与其他bean属性的名称是一样的,那么将自动装配它. 例如,如果“customer” bean公开一个“address”属性,Sprin ...

  5. sublime文件对比插件--sublimerge

    网上很多文件对比的基本都要收费,所以还是干脆看看sublime有没插件算了. 结果还是有一个:sublimerge 1 先安装该插件: 2 然后在sublime下都打开要对比的两个文件: 3 然后在其 ...

  6. 【openCV学习笔记】在Mac上配置openCV步骤详解

    (1)安装Homebrew:(需要Ruby) 注:因为snow leopard 以后已经自带Ruby了,所有可以不用自己安装Ruby. 看一下Homebrew的官网: http://mxcl.gith ...

  7. [转载]amba_device使用分析

    什么是AMBA? ---AMBA是一个片内总线规范. ARM官网的介绍:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0 ...

  8. DSP SYS/BIOS开发

    https://blog.csdn.net/lg1259156776/article/details/80695318

  9. Vue.js:自定义指令

    ylbtech-Vue.js:自定义指令 1.返回顶部 1. Vue.js 自定义指令 除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令. 下面我们注册一 ...

  10. 1142 Maximal Clique

    题意:给出一个图,定义这样一个结点子集subset,若subset中的任意两结点不都相邻,则称之为Not a Clique:若subset中的任意两结点都相邻,则称之为Clique:若subset中的 ...