本文主要使用实例对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. MongoDB:MapReduce基础及实例

    背景 MapReduce是个非常灵活和强大的数据聚合工具.它的好处是可以把一个聚合任务分解为多个小的任务,分配到多服务器上并行处理. MongoDB也提供了MapReduce,当然查询语肯定是Java ...

  2. AtCoder Grand Contest 017 题解

    A - Biscuits 题目: 给出 \(n\) 个物品,每个物品有一个权值. 问有多少种选取方式使得物品权值之和 \(\bmod\space 2\) 为 \(p\). \(n \leq 50\) ...

  3. NOIP2013DAY1题解

    T1转圈游戏 十月のsecret 题解:快速幂 代码: #include<iostream> #include<cstring> #include<cstdio> ...

  4. shell查看执行过程及时间变量

    sh -xv test.sh    #加参数xv查看shell执行过程. Shell 调用系统时间变量 获取今天时期:`date +%Y%m%d` 或 `date +%F` 或date +%Y-%m- ...

  5. 多线程设计模式(二):Future模式

    一.什么是Future模型: 该模型是将异步请求和代理模式联合的模型产物.类似商品订单模型.见下图: 客户端发送一个长时间的请求,服务端不需等待该数据处理完成便立即返回一个伪造的代理数据(相当于商品订 ...

  6. 事务之四:Spring事务--原理

    一.Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: ...

  7. Vue.js:循环语句

    ylbtech-Vue.js:循环语句 1.返回顶部 1. 循环语句 循环使用 v-for 指令. v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组并且 ...

  8. JS面向对象编程,对象,属性,方法。

    document.write('<script type="text/javascript" src="http://api.map.baidu.com/api?v ...

  9. 转:oracle几组重要的常见视图-v$process,v$session,v$session_wait,v$session_event

    v$process 本视图包含当前系统oracle运行的所有进程信息.常被用于将oracle或服务进程的操作系统进程ID与数据库session之间建立联系.在某些情况下非常有用: 1 如果数据库瓶颈是 ...

  10. 登陆验证系统实例-三种(cookie,session,auth)

    登陆验证 因为http协议是无状态协议,但是我们有时候需要这个状态,这个状态就是标识 前端提交from表单,后端获取对应输入值,与数据库对比,由此对象设置一个标识,该对象 在别的视图的时候,有此标识, ...