Hive HiveQL基础知识及常用语句总结

https://blog.csdn.net/u012386109/article/details/78214894

https://blog.csdn.net/u010385646/article/details/53167707

基础语句

CREATE DROP 建表、删表

  • 建表
--------------------------------------
-- 1. 直接建表
--------------------------------------

-- 创建非分区表时,省去后半部分即可
create table if not exists table_name(
id string comment 'id ',
num string comment '数值'  
)
partitioned by (
ym string comment  '月份 ' 
);

--------------------------------------
-- 2. 复制其他表的表结构
--------------------------------------
create table if not exists new_table like old_table;

--------------------------------------
-- 3. 从其他表选取数据创建并插入新表
--------------------------------------
create table if not exists new_table as
select * from  old_table;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 删表
drop table table_name ;
  • 1

ALTER 更改表结构

分区

  • 添加分区
alter table table_name 
add if not exists partition (y='2016',m='12');
  • 1
  • 2
  • 删除分区
ALTER TABLE table_name DROP IF EXISTS PARTITION (ym='201706');
  • 1
  • 重命名分区
 ALTER TABLE table_name PARTITION (y='2017',m='05') 
 RENAME TO PARTITION (y='2017',m='06'); 
  • 1
  • 2

  • 删除列
ALTER TABLE table_name DROP COLUMN id;
  • 1
  • 增加列
Alter table table_name add COLUMNS (id string comment '代号');
  • 1
  • 修改列 (此处可用于 修改字段注释)
ALTER TABLE table_name CHANGE id level string comment '层级代号';
  • 1
  • 替换列
ALTET TABLE table_name REPLACE COLUMNS
(id_new string COMMENT '新字段1', level_new string COMMENT '新字段2');
  • 1
  • 2

  • 重命名表名
ALTER TABLE old_table RENAME TO new_table;
  • 1

INSERT 插入

  • 插入单条数据 (Hive 已支持单条插入)
 insert into table_name  values(201705,'lol');
  • 1
  • 插入分区表
 insert overwrite table  table_name   PARTITION (y='2017',m='01')
 select * 
 from table_name_2 
  where pt = concat('2017','01'); 
  • 1
  • 2
  • 3
  • 4

LOAD 载入

  • 重写载入分区表 (非分区表同理)
LOAD DATA LOCAL INPATH 'total.txt' overwrite into table table_name partition (y='2016',m='12');
  • 1

其他语句

  • 其他基础SQL类似的语句不再赘述,此处再多列举几个常用语句:
-- 列举库或表
SHOW DATABASES/TABLES;
-- 根据关键字查找库或表
SHOW DATABASES/TABLES LIKE "*keyword*";
-- 列举所有函数
SHOW FUNCTIONS;
-- 查看分区
SHOW PARTITIONS test_table;
-- 查看建表语句
SHOW CREATE TABLE table_name;
-- 详细描述,包括建表时间、最后更新时间、行数统计等。
DESC FORMATTED test_table;
-- 解释语句
EXPLAIN select * from dual;
-- 清空表
truncate table table_name;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

函数、技巧、方法

  • 执行顺序理解 
    根据 explain 语句的使用发现,在执行以下语句时: 
    TableScan步骤,where条件中若有分区筛选条件且目标分区确实存在、且判断方式为=时,自动进行过滤, 然后再在Filter Operator进行其他条件的筛选: 
    predicate: (latitude is not null and (UDFToDouble(longitude) > 100.0) AND (UDFToDouble(ym) > 201701.0)) (type: boolean) 
    predicate: (lat_avg is not null and lng_avg is not null) (type: boolean) 
    所以, 先join在where和先where在join是等等价的
  select b.*, a.name,a.price,a.city  
  from table_name_a a 
  join table_name_b b
  on round(b.lng_avg,2) = round(a.longitude,2) 
  and round(b.lat_avg,2) = round(a.latitude,2) 
  where  a.longitude  >100  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • shell内通过hive -v " "调用执行HiveQL语句时,如需要注释,请注意转义问题

    1. 注释的那条语句不能含有分号;
    2. 注释语句后接语句尽量避免导jar包的语句
    3. 避免使用 /* */
  • 选择除某几个字段外的所有字段 
    当某个表的字段特别多,若想选取除某几个字段外的所有字段时,这时语句写起来就会很麻烦,比如有时两个表join的条件的字段名相同时,只能保留一个字段。但有一个方法可以解决这个问题,如下:

set hive.support.quoted.identifiers=none;
select `(y|m|d)?+.+` from dual;
  • 1
  • 2

需注意:

括号内不能有空格

在shell里调用时需要对这个反引号进行转义

  • 通过concat_wscollect_setstr_to_map的使用,实现字符串转map
str_to_map(concat_ws(',',collect_set(concat_ws(':',key, cast(value as string)))))
  • 1
  • avg()函数会自动剔除NULL,总数除以非NULL个数
  • 字符串截取函数substrsubstring是等价的 
    substr(string A, int start, int len) 
    substring(string A, int start, int len)
  • x between a and b 等同于 a<= x <=b

  • 子查询加最好要加别称 
    报错:Failed rule: ‘identifier’ in subquery source 
    解决:子查询加 别称

  • 设置队列问题, mapred.job.queue.namemapreduce.job.queuename

set mapred.job.queue.name=queue_xx;
  • 1

MRv2重新命名了MRv1中的所有配置参数,但兼容MRv1中的旧参数,只不过会打印一条警告日志提示用户参数过期。详见此篇博文

  • 查询表的实际更新情况 
    desc formatted 的结果往往只有CreateTimeLastAccessTime经常为UNKNOWN的状态,可以用hadoop 指令去查询数据文件的真实更新时间:hadoop fs ‐ls truePath/databaseName.db/tableName/

调优

占个坑,有时间再来填

Hive里的坑点

  • limit m,n 的问题 
    使用语句:create table a as select * from b limit m,n时,会导致新建表a内无数据,解决办法: 
    1. 看似可以其实并不好使: create table a as select * from (select * from b limit m,n ) t
    2. 解决: 使用row_number() 加序号,根据序号选取
  • NULL 值问题 
    1. length(NULL) 等于NULL
    2. NULL空字符串
      由下可见:NULL不可以与字符串或数值比较,''可与字符串比较但不可与数值比较
hive (xx_safe)> select * from dual;
OK
dual.lol
100
50
1
1
2
fangjiale
NULL
   --(此处为'')
hive (xx_safe)> select * from dual where lol !='1';
OK
dual.lol
fangjiale
100
50
2
   --(此处为'')  
hive (xx_safe)> select * from dual where lol !=1;
OK
dual.lol
100
50
2

Hive--HiveQL与SQL区别

2016年11月15日 08:53:53

阅读数:14601

链接

1.hive内联支持什么格式?
2.分号字符注意什么问题?
3.hive中empty是否为null?
4.hive是否支持插入现有表或则分区中?
5.hive是否支持INSERT INTO 表 values()?


1、Hive不支持等值连接 
•SQL中对两表内联可以写成:
•select * from dual a,dual b where a.key = b.key;
•Hive中应为
•select * from dual a join dual b on a.key = b.key; 
而不是传统的格式:
SELECT t1.a1 as c1, t2.b1 as c2FROM t1, t2
WHERE t1.a2 = t2.b2

2、分号字符
•分号是SQL语句结束标记,在HiveQL中也是,但是在HiveQL中,对分号的识别没有那么智慧,例如:
•select concat(key,concat(';',key)) from dual;
•但HiveQL在解析语句时提示:
        FAILED: Parse Error: line 0:-1 mismatched input '<EOF>' expecting ) in function specification
•解决的办法是,使用分号的八进制的ASCII码进行转义,那么上述语句应写成:
•select concat(key,concat('\073',key)) from dual;

3、IS [NOT] NULL
•SQL中null代表空值, 值得警惕的是, 在HiveQL中String类型的字段若是空(empty)字符串, 即长度为0, 那么对它进行IS NULL的判断结果是False.

4、Hive不支持将数据插入现有的表或分区中,
仅支持覆盖重写整个表,示例如下:

  1. INSERT OVERWRITE TABLE t1  
  2. SELECT * FROM t2;

复制代码

5、hive不支持INSERT INTO 表 Values(), UPDATE, DELETE操作
    这样的话,就不要很复杂的锁机制来读写数据。
    INSERT INTO syntax is only available starting in version 0.8。INSERT INTO就是在表或分区中追加数据。

6、hive支持嵌入mapreduce程序,来处理复杂的逻辑
如:

  1. FROM (  
  2. MAP doctext USING 'python wc_mapper.py' AS (word, cnt)  
  3. FROM docs  
  4. CLUSTER BY word  
  5. ) a  
  6. REDUCE word, cnt USING 'python wc_reduce.py';  

复制代码

--doctext: 是输入
--word, cnt: 是map程序的输出

--CLUSTER BY: 将wordhash后,又作为reduce程序的输入



并且map程序、reduce程序可以单独使用,如:

  1. FROM (  
  2. FROM session_table  
  3. SELECT sessionid, tstamp, data  
  4. DISTRIBUTE BY sessionid SORT BY tstamp  
  5. ) a  
  6. REDUCE sessionid, tstamp, data USING 'session_reducer.sh';  

复制代码

-DISTRIBUTE BY: 用于给reduce程序分配行数据

7、hive支持将转换后的数据直接写入不同的表,还能写入分区、hdfs和本地目录
这样能免除多次扫描输入表的开销。

  1. FROM t1  
  2.   
  3. INSERT OVERWRITE TABLE t2  
  4. SELECT t3.c2, count(1)  
  5. FROM t3  
  6. WHERE t3.c1 <= 20  
  7. GROUP BY t3.c2  
  8.   
  9. INSERT OVERWRITE DIRECTORY '/output_dir'  
  10. SELECT t3.c2, avg(t3.c1)  
  11. FROM t3  
  12. WHERE t3.c1 > 20 AND t3.c1 <= 30  
  13. GROUP BY t3.c2  
  14.   
  15. INSERT OVERWRITE LOCAL DIRECTORY '/home/dir'  
  16. SELECT t3.c2, sum(t3.c1)  
  17. FROM t3  
  18. WHERE t3.c1 > 30  
  19. GROUP BY t3.c2;  

复制代码

猜你喜欢

转载自blog.csdn.net/hlang8160/article/details/81488013