Hive HQL数据操作、数据查询

时间:2022-05-19 23:11:57

一、HQL 数据操作


本方内容来源《Hadoop海量数据处理技术详解与项目实战》人民邮电出版社
建库建表等参考这里
http://blog.csdn.net/xundh/article/details/71404376#t4

1.装载数据

LOAD DATA INPATH '/user/hadoop/o' INTO TABLE test;

如果test表是一个分区表,则在HQL中指定区分:

LOAD DATA INPATH '/USER/HADOOP/O' OVERWRITE INTO TABLE test3 PARTITION(part="a");

从本地直接加载数据表表中

LOAD DATA LOCAL INPATH '/HOME/HADOOP/O' INTO TABLE test;

Hive在加载数据时不会对数据格式进行任何的验证,需要用户自己保证数据格式与表定义的格式一致。

2.通过查询语句向表中插入数据

INSERT OVERWRITE TABLE test SELECT * FROM source;

同样,当test是分区表时,必须指定分区

INSERT OVERWRITE TABLE test PARTITION (part='a') SELECT id,name FROM source;

Hive0.7以后开始支持INSERT INTO,追加的方式。

通过一次查询,产生多个不相交的输出

FROM source
INSERT OVERWRITE TABLE test PARTITION (part='a')
SELECT id,name WHERE id>=0 AND id<100
INSERT OVERWRITE TABLE test PARTITION (part='b')
SELECT id,name WHERE id>=100 AND id<200
...

这样只通过一次对source表的查询,就将符合条件的数据插入test表的各个分区。要使用这个特性,FROM子句要写在前面。

3.利用动态分区向表中插入数据

支持基于查询参数自动推断出需要创建的分区

INSERT OVERWRITE TABLE test PARTITION(time) SELECT id,modify_time FROM source;

Hive 会根据SELECT语句中的最后一个查询字段作为动态分区的依据,而不是根据字段名来选择。如果指定了n 个动态分区的字段,Hive会将select语句中最后n个字段作为动态分区的依据。
上述语句,Hive会根据modify_time不同的值创建分区。
Hive默认没有开启动态分区,开启语句:

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nostrict; 允许所有分区都是动态的
  • hive.exec.max.dynamic.partitions.pernode 每个Mapper或Reducer可以创建的最大分区数
  • hive.exec.max.dynamic.partitions 一条动态分区创建语句能够创建的最大分区数
  • hive.exec.max.created.files 一个MapReduce作业能够创建的最大文件数

4.通过CTAS加载数据

CREATE TABLE test AS SELECT id,name FROM source;

5.导出数据

INSERT OVERWRITE DIRECTORY '/user/hadoop/r' SELECT * FROM test;
INSERT OVERWRITE LOCAL DIRECTORY '/home/hadoop/r' SELECT * FROM test;

如果Hive表中的数据正好满足用户需要的数据格式,可以直接复制

hadoop dfs -cp /user/hive/warehouse/source_table /user/hadoop/

6.删除分区

ALTER TABLE shphonefeature DROP IF EXISTS PARTITION(year = 2015, month = 10, day = 1);删除掉指定分区

二、数据查询

1.SELECT

SELECT col1,col2 FROM table;
SELECT t.col1 c1,t.col2 c2 FROM table t;

2.嵌套查询

SELECT l.name,r.course FROM (SELECT id,name FROM left) l JOIN (select id ,course FROM right) r ON l.id=r.id;

3.正则表达式选择列

SELECT 'user.*' FROM test; 如列:user.name,user.age将被返回

4.限制数量

SELECT * FROM test LIMIT 100;

5.需要对某列值处理

SELECT id,name,sex,
CASE
WHEN sex='M' THEN '男'
WHEN sex='F' THEN '女'
ELSE '无效数据'
END
FROM student;

6.条件限制

支持常见的=、<>,!=,A IS NULL,A [NOT] LIKE B,A RLIKE B,A REGEXP B等

SELECT * FROM student WHERE age=18;

7.分组、聚合

SELECT COUNT(*) FROM student GROUP BY age;
SELECT AVG(age) FROM student GROUP BY classId;
SELECT name,AVG(age) FROM student where sex='F' GROUP BY classId HAVING AVG(age)>18;

8.JOIN

INNER JOIN内连接
LEFt/RIGHT OUTER JOIN/右外连接
FULL OUTER JOIN 全外连接
LEFT-SEMI JOIN 左半连接
map-side JOIN map阶段,将小表读到内存中去,直接在mapjoin。用户可以通过设置hive.auto.convert.join=true来开启自动优化,通过hive.mapjoin.smalltable.filesize来定义小表的大小,默认为25000000字节。
多表JOIN

9.ORDER BY和 SORT BY

当reducer的个数为1时,两者相同。
当reducer个数不止一个时,输出结果会有重合。SORT BY是控制每个reducer内的排序。

10.DISTRIBUTE BY和SORT BY

DISTRIBUTE BY可以控制某些数据进入同一个Reducer,这样经过SORT BY以后,可以得到全局排序的结果。
SELECT col1,col2 FROM ss DISTRIBUTE BY col1 SORT BY col1,col2;

11.CLUSTER BY

如果在使用DISTRIBUTE BY 和SORT BY语句时,DISTRIBUTE BY和SORT BY涉及的列完全相同,并且采用升序排列,可以使用CLSTER BY代替DISTRIBUTE BY和SORT BY

12.分桶和抽样

有时候需要对数据进行抽样,Hive提供了对表分桶抽样

SELECT * FROM test TABLESAMPLE(BUCKET 3 OUT OF 10 ON id);

对于BUCKET x OUT OF y ON z,其中y表示y个桶,x表示取第x个桶,z表示分桶的依据是将z列的哈希值散列再除以y的余数。如果不指定z,可以采取随机列抽样的方式。

SELECT * FROM test TABLESAMPLE(BUCKET 3 OUT OF 10 ON RAND());

在建表时,可以指定为分桶表,那在抽样会更加高效

set hive.enforce.bucketing=true;
CREATE TABLE buckettable (id INT) CLUSTERED BY (id) INTO 4 BUCKETS;

该表将被划分为4个桶,然后执行INSERT语句

INSET OVERWRITE TABLE buckettable SELECT * FROM source;

数据将被划分为4个文件存放在表路径下,每个文件代表一个桶。

13.UNION ALL

SELECT r.id,r.price
FROM(
SELECT m.id,m.price FROM monday m
UNION ALL
SELECT t.id,t.price FROM tuesday t)r

Hive不支持直接UNION ALL,必须进行嵌套查询。