hive 笔记

下面以sales和things表为例。这两个表定义如下:
hive> SELECT * FROM sales;
Joe 2
Hank 4
Ali 0
Eve 3
Hank 2
hive> SELECT * FROM things;
2 Tie
4 Coat
3 Hat
1 Scarf

1.     Inner joins

hive> SELECT sales.*, things.*
> FROM sales JOIN things ON (sales.id = things.id);
Joe 2 2 Tie
Hank 2 2 Tie
Eve 3 3 Hat
Hank 4 4 Coat

以集合论的语言描述,可以表示为:

也就说,只有两个表匹配上,有交集,才会出现在最终结果中。

2.     LEFT OUTER JOIN

hive> SELECT sales.*, things.*
> FROM sales LEFT OUTER JOIN things ON (sales.id = things.id);
Ali 0 NULL NULL
Joe 2 2 Tie
Hank 2 2 Tie
Eve 3 3 Hat
Hank 4 4 Coat
以集合论的语言描述,可以表示为:

也就是说,左表(sales)和右表(things)有交集的,会出现在最终结果里,如上面图中的黑色区域。此外,出现在sales(图中红色的部分),但是没有出现在things,最终结果会出现sales的记录,而things的部分则以NULL补充。

3.     RIGHT OUTER JOIN

hive> SELECT sales.*, things.*
> FROM sales RIGHT OUTER JOIN things ON (sales.id = things.id);
NULL NULL 1 Scarf
Joe 2 2 Tie
Hank 2 2 Tie
Eve 3 3 Hat
Hank 4 4 Coat
以集合论的语言描述,可以表示为:

RIGHT OUTER JOIN只是将LEFT OUTER JOIN的两个表对换而已。

4.     FULL OUTER JOIN

hive> SELECT sales.*, things.*
> FROM sales FULL OUTER JOIN things ON (sales.id = things.id);
Ali 0 NULL NULL
NULL NULL 1 Scarf
Joe 2 2 Tie
Hank 2 2 Tie
Eve 3 3 Hat
Hank 4 4 Coat
以集合论的语言描述,可以表示为:

FULL OUTER JOIN可以理解为LEFT OUTER JOIN + RIGHT OUTER JOIN。

5.     LEFT SEMI JOIN

Hive doesn’t support IN subqueries (at the time of this writing), but you can use a LEFT SEMI JOIN to do the same thing.
Consider this IN subquery, which finds all the items in the things table that are in the sales table:
SELECT *
FROM things
WHERE things.id IN (SELECT id from sales);

We can rewrite it as follows:
hive> SELECT *
> FROM things LEFT SEMI JOIN sales ON (sales.id = things.id);
2 Tie
3 Hat
4 Coat
从LEFT SEMI JOIN的定义看,只有出现在sales中的id,才会出现在最终结果里。且由于采用的是IN关键字,因此,从IN (SELECT id from sales)出来的id已经是去过重的。

6.     Map joins

hive> SELECT /*+ MAPJOIN(things) */ sales.*, things.*
> FROM sales JOIN things ON (sales.id = things.id);
Joe 2 2 Tie
Hank 4 4 Coat
Eve 3 3 Hat
Hank 2 2 Tie
Map joins主要是一种优化操作,通过避免reduce端的操作,加速job运行时间。实际中,如何一个表的大小在几十M,均可以通过map join加速。
Map join的实际操作应该是,将小表通过分布式缓存发布到集群上。每个mapper将该小表的join
key加载到自己的内存中,通过类似hash表的方式进行存储。Mapper每读进一条记录,就会查查当前记录的key是否在该hash表中,如果在,则
输出。这样就避免了reduce的操作。

7.     UNION ALL
假设表sales用示意图描述如下,因为表本来就是关系,因此用矩形表示:

things表如下:

则UNION ALL的效果如下:

也就是将两张表追加到了一起。

8.     Subqueries
需要注意的是hive只支持在FROM子句中使用Subqueries。
因为Subqueries子查询相对复杂,这里重点介绍下如何写好Subqueries。

以下是一个复杂的hive例子:
SELECT * FROM
(
     SELECT
uid,sessionid,stepid,time,position,source,action,request,response,cellphone,other
FROM log_route_car_filtered WHERE dt=‘20140517‘
     UNION ALL
     SELECT client.uid,client.sessionid,client.stepid,client.time,client.position,client.source,client.action,
          client.request,client.response,client.cellphone,client.other
     FROM log_client_filtered client
     WHERE (dt=‘20140517‘ AND other[‘date‘]=‘20140517‘)
          OR (dt=‘20140518‘ AND other[‘date‘]=‘20140517‘)
     LEFT SEMI JOIN
     (
          SELECT DISTINCT uid, sessionid FROM log_route_car_filtered WHERE dt=‘20140517‘
     ) unique_route
     ON (client.uid=unique_route.uid AND client.sessionid=unique_route.sessionid)
) merge
WHERE uid RLIKE ‘^[\\w-]+$‘
DISTRIBUTE BY uid
SORT BY uid,sessionid,CAST(stepid AS INT),time;

为了方便叙述,我用不同的颜色标记了query的主要结构。
外头的SELECT * FROM从一个复杂的UNION ALL结果中提取结果,并通过WHERE,DISTRIBUTE BY和SORT BY对结果进行过滤。

这里的主要问题是UNION ALL后的SELECT语句存在问题,会导致hive执行报错,而且错误信息很模糊。
因此我们把这部分结果单独拿出来进行分析:
SELECT client.uid,client.sessionid,client.stepid,client.time,client.position,client.source,client.action,
     client.request,client.response,client.cellphone,client.other
FROM log_client_filtered client
WHERE (dt=‘20140517‘ AND other[‘date‘]=‘20140517‘)
     OR (dt=‘20140518‘ AND other[‘date‘]=‘20140517‘)
LEFT SEMI JOIN
(
     SELECT DISTINCT uid, sessionid FROM log_route_car_filtered WHERE dt=‘20140517‘
) unique_route
ON (client.uid=unique_route.uid AND client.sessionid=unique_route.sessionid)

LEFT SEMI JOIN的语法框架如下:
SELECT * FROM tabel1 LEFT SEMI JOIN table2 ON (tabel1.id = tabel2.id);
不包括WHERE子句,但在这里我们又想通过WHERE子句过滤包含指定日期的结果,怎么办呢?
这时我们可以将WHERE子句包装进一个Subquery,如下:
SELECT * FROM
(
     SELECT uid,sessionid,stepid,time,position,source,action,.request,response,cellphone,other
     FROM log_client_filtered
     WHERE (dt=‘20140517‘ AND other[‘date‘]=‘20140517‘) OR (dt=‘20140518‘ AND other[‘date‘]=‘20140517‘)
) client
LEFT SEMI JOIN
(
     SELECT DISTINCT uid, sessionid FROM log_route_car_filtered WHERE dt=‘20140517‘
) unique_route
ON (client.uid=unique_route.uid AND client.sessionid=unique_route.sessionid)

这样一个查询就满足了LEFT SEMI JOIN的语法结构,问题解决。

PS:这里我只说明了map join的操作原理,大家可以想想其它join操作的实现过程,应该都是不难的,网上资料也很多。

时间: 2024-10-05 23:00:18

hive 笔记的相关文章

Hive笔记整理(一)

[TOC] Hive笔记整理(一) Hive Hive由facebook贡献给Apache,是一款建立在Hadoop之上的数据仓库的基础框架. 数据仓库 特点--关于存放在数据仓库中的数据的说明: 是能够为企业的各个级别的决策提供数据支撑的数据 其实说白了,就是一个存放数据的仓库 数据库和数据仓库之间的区别 现代数据仓库,是构建在数据库之上的,使用数据库作为载体存放数据. 数据仓库着重强调的是存放的历史数据,数据库着重强调的是存放在线的数据. 数据仓库着重强调的是OLAP的操作,数据库着重强调的

Hive笔记整理(二)

[TOC] Hive笔记整理(二) Hive中表的分类 managed_table-受控表.管理表.内部表 表中的数据的生命周期/存在与否,受到了表结构的影响,当表结构被删除的,表中的数据随之一并被删除. 默认创建的表就是这种表. 可以在cli中通过desc extended tableName来查看表的详细信息,当然也可以在MySQL中hive的元数据信息表TBLS中查看. external_table-外部表 表中的数据的生命周期/存在与否,不受到了表结构的影响,当表结构被删除的,表中对应数

Hive笔记整理(三)

[TOC] Hive笔记整理(三) Hive的函数 Hive函数分类 函数的定义和java.mysql一样,有三种. UDF(User Definition Function 用户定义函数) 一路输入,一路输出 sin(30°)=1/2 UDAF(User Definition Aggregation Function 聚合函数) 多路输入,一路输出 max min count sum avg等等 UDTF(User Definition Table Function 表函数) 一路输入,多路输

Hadoop之——Hive笔记

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46496123 1.Hive 1.1在hadoop生态圈中属于数据仓库的角色.他能够管理hadoop中的数据,同时可以查询hadoop中的数据. 本质上讲,hive是一个SQL解析引擎.Hive可以把SQL查询转换为MapReduce中的job来运行. hive有一套映射工具,可以把SQL转换为MapReduce中的job,可以把SQL中的表.字段转换为HDFS中的文件(夹)以及文

hive笔记(自学整理的)

第一部分:用户管理 创建用户:CREATE DATABASE XXX 查看用户:SHOW DATABASES; 关键查看用户:show databases like 'de.*' 讲解:创建一个用户就等于在物理目录下创建了一个文件,该文件是以.db结尾的, 默认的路径是:/user/hive/warehouse/zqx.db 创建用户时可以指定路径: create database XXX location '/my/preferred/directory' 讲解:为后期维护方便,可以创建用户时

hive笔记

1.hive建表 多种分隔符,支持list,map结构 https://stackoverflow.com/questions/18011252/how-to-define-nested-collection-items-in-hive 2.hive导入json数据  自定义SerDe http://www.cnblogs.com/likai198981/archive/2013/05/05/3061499.html

docker安装hive笔记

前两篇文章介绍了docker的基本命令如何安装hadoop 那么大家会比较了解docker的基本语法的安装过程.那么咱们今天来一起安装一下hive. 安装 1.下载gitHub,地址:https://github.com/prasanthj/docker-hive-on-tez.如果背墙了,可以选择下载zip.进入目录之后就能看见如下内容: @~/git/github/docker-hive-on-tez-master $ ls Dockerfile datagen.py hive-log4j.

hive笔记-----查询数据

一.排序和聚集 hive中的order by能够预期产生完全排序的结果,但这个排序的过程只是使用一个reduce任务来完成的,这个面对大规模的数据集肯定不可行的 因此 sort by出现,它可以为每个reduce任务产生一个排序文件 distribute by 可以控制某个特定行应该到哪个reducer,目的在于进行后续的聚集操作 例如 from record2 select year,temperture distribute by year sort by year asc,temperat

Hive笔记之数据库操作

创建数据库 hive创建数据库的最简单写法和mysql差不多: create database foo; 仅当名为foo的数据库当前不存在时才创建: create database if not exists foo; 创建数据库时指定位置,这个位置一般是在hdfs上的位置: create database foo location '/db/foo'; 查看已经创建的数据库: show databases ; 使用通配符查看foo开头的数据库: show databases like 'foo