# 追加操作 load data local inpath '/export/servers/hivedatas/student.csv'intotable student;
# 覆盖操作 load data local inpath '/export/servers/hivedatas/student.csv' overwrite intotable student;
从hdfs文件系统向表中加载数据
1 2 3 4
load data inpath '/hivedatas/techer.csv'intotable techer;
# 加载数据到指定分区 load data inpath '/hivedatas/techer.csv'intotable techer partition(cur_date=20201210);
注意: 1.使用 load data local 表示从本地文件系统加载,文件会拷贝到hdfs上 2.使用 load data 表示从hdfs文件系统加载,文件会直接移动到hive相关目录下,注意不是拷贝过去,因为hive认为hdfs文件已经有3副本了,没必要再次拷贝了 3.如果表是分区表,load 时不指定分区会报错 4.如果加载相同文件名的文件,会被自动重命名
对分区表的操作
创建分区表的语法
1
createtable score(s_id string, s_score int) partitioned by (month string);
SELECT [ALL|DISTINCT] select_expr, select_expr, ... FROM table_reference [WHERE where_condition] [GROUPBY col_list [HAVINGcondition]] [CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY|ORDERBY col_list] ] [LIMIT number]
注意: 1、order by 会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。 2、sort by不是全局排序,其在数据进入reducer前完成排序。因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只保证每个reducer的输出有序,不保证全局有序。 3、distribute by(字段)根据指定的字段将数据分到不同的reducer,且分发算法是hash散列。 4、Cluster by(字段) 除了具有Distribute by的功能外,还会对该字段进行排序。 因此,如果分桶和sort字段是同一个时,此时,cluster by = distribute by + sort by
WHERE语句
1
select*from score where s_score <60;
注意: 小于某个值是不包含null的,如上查询结果是把 s_score 为 null 的行剔除的
GROUP BY 分组
1 2 3 4
# select s_id ,avg(s_score) from score groupby s_id;
分组后对数据进行筛选,使用having select s_id ,avg(s_score) avgscore from score groupby s_id having avgscore >85;
注意: 如果使用 group by 分组,则 select 后面只能写分组的字段或者聚合函数 where和having区别: 1 having是在 group by 分完组之后再对数据进行筛选,所以having 要筛选的字段只能是分组字段或者聚合函数 2 where 是从数据表中的字段直接进行的筛选的,所以不能跟在gruop by后面,也不能使用聚合函数
join 连接
1 2 3 4 5 6 7 8 9 10 11
# INNERJOIN 内连接:只有进行连接的两个表中都存在与连接条件相匹配的数据才会被保留下来 select*from techer t [inner] join course c on t.t_id = c.t_id; -- inner 可省略
LEFTOUTERJOIN 左外连接:左边所有数据会被返回,右边符合条件的被返回 select*from techer t leftjoin course c on t.t_id = c.t_id; -- outer可省略
RIGHTOUTERJOIN 右外连接:右边所有数据会被返回,左边符合条件的被返回、 select*from techer t rightjoin course c on t.t_id = c.t_id;
FULLOUTERJOIN 满外(全外)连接: 将会返回所有表中符合条件的所有记录。如果任一表的指定字段没有符合条件的值的话,那么就使用NULL值替代。 SELECT*FROM techer t FULLJOIN course c ON t.t_id = c.t_id ;
注:1. hive2版本已经支持不等值连接,就是 join on条件后面可以使用大于小于符号了;并且也支持 join on 条件后跟or (早前版本 on 后只支持 = 和 and,不支持 > < 和 or) 2.如hive执行引擎使用MapReduce,一个join就会启动一个job,一条sql语句中如有多个join,则会启动多个job
注意:表之间用逗号(,)连接和 inner join 是一样的 select * from table_a,table_b where table_a.id=table_b.id; 它们的执行效率没有区别,只是书写方式不同,用逗号是sql 89标准,join 是sql 92标准。用逗号连接后面过滤条件用 where ,用 join 连接后面过滤条件是 on。
order by 排序
1 2 3
# 全局排序,只会有一个reduce ASC(ascend): 升序(默认) DESC(descend): 降序 SELECT*FROM student s LEFTJOIN score sco ON s.s_id = sco.s_id ORDERBY sco.s_score DESC;
注意:order by 是全局排序,所以最后只有一个reduce,也就是在一个节点执行,如果数据量太大,就会耗费较长时间
sort by 局部排序
1 2 3 4 5 6 7 8 9 10 11 12 13
# 每个MapReduce内部进行排序,对全局结果集来说不是排序。
# 设置reduce个数 set mapreduce.job.reduces=3;
# 查看设置reduce个数 set mapreduce.job.reduces;
# 查询成绩按照成绩降序排列 select*from score sort by s_score; # 将查询结果导入到文件中(按照成绩降序排列) insert overwrite local directory '/export/servers/hivedatas/sort'select*from score sort by s_score;
distribute by 分区排序
1 2 3 4 5 6 7
# distribute by:类似MR中partition,进行分区,结合sort by使用
# 设置reduce的个数,将我们对应的s_id划分到对应的reduce当中去 set mapreduce.job.reduces=7;
# 通过distribute by 进行数据的分区 select*from score distribute by s_id sort by s_score;
语法: if(boolean testCondition, T valueTrue, T valueFalseOrNull) 返回值: T 说明: 当条件testCondition为TRUE时,返回valueTrue;否则返回valueFalseOrNull hive>select if(1=2,100,200) ; 200 hive>select if(1=1,100,200) ; 100
非空查找函数: coalesce
1 2 3 4 5
语法: coalesce(T v1, T v2, …) 返回值: T 说明: 返回参数中的第一个非空值;如果所有值都为NULL,那么返回NULL hive>selectcoalesce(null,'100','50') ; 100
条件判断函数:case when (两种写法,其一)
1 2 3 4 5
语法: casewhen a then b [when c then d]* [else e] end 返回值: T 说明:如果a为TRUE,则返回b;如果c为TRUE,则返回d;否则返回e hive>selectcasewhen1=2then'tom'when2=2then'mary'else'tim'endfrom tableName; mary
条件判断函数:case when (两种写法,其二)
1 2 3 4 5
语法: case a when b then c [when d then e]* [else f] end 返回值: T 说明:如果a等于b,那么返回c;如果a等于d,那么返回e;否则返回f hive>Selectcase100when50then'tom'when100then'mary'else'tim'endfrom tableName; mary
语法: substr(string A, intstart),substring(string A, intstart) 返回值: string 说明:返回字符串A从start位置到结尾的字符串 hive>select substr('abcde',3) from tableName; cde hive>selectsubstring('abcde',3) from tableName; cde hive>select substr('abcde',-1) from tableName; (和ORACLE相同) e
字符串截取函数:substr,substring
1 2 3 4 5 6 7 8 9
语法: substr(string A, intstart, int len),substring(string A, intstart, int len) 返回值: string 说明:返回字符串A从start位置开始,长度为len的字符串 hive>select substr('abcde',3,2) from tableName; cd hive>selectsubstring('abcde',3,2) from tableName; cd hive>selectsubstring('abcde',-2,2) from tableName; de
字符串转大写函数:upper,ucase
1 2 3 4 5 6 7
语法: upper(string A) ucase(string A) 返回值: string 说明:返回字符串A的大写格式 hive>selectupper('abSEd') from tableName; ABSED hive>select ucase('abSEd') from tableName; ABSED
字符串转小写函数:lower,lcase
1 2 3 4 5 6 7
语法: lower(string A) lcase(string A) 返回值: string 说明:返回字符串A的小写格式 hive>selectlower('abSEd') from tableName; absed hive>select lcase('abSEd') from tableName; absed
去空格函数:trim
1 2 3 4 5
语法: trim(string A) 返回值: string 说明:去除字符串两边的空格 hive>selecttrim(' abc ') from tableName; abc
左边去空格函数:ltrim
1 2 3 4 5
语法: ltrim(string A) 返回值: string 说明:去除字符串左边的空格 hive>select ltrim(' abc ') from tableName; abc
右边去空格函数:rtrim
1 2 3 4 5
语法: rtrim(string A) 返回值: string 说明:去除字符串右边的空格 hive>select rtrim(' abc ') from tableName; abc
正则表达式替换函数:regexp_replace
1 2 3 4 5
语法: regexp_replace(string A, string B, string C) 返回值: string 说明:将字符串A中的符合java正则表达式B的部分替换为C。注意,在有些情况下要使用转义字符,类似oracle中的regexp_replace函数。 hive>select regexp_replace('foobar', 'oo|ar', '') from tableName; fb
正则表达式解析函数:regexp_extract
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
语法: regexp_extract(string subject, string pattern, int index) 返回值: string 说明:将字符串subject按照pattern正则表达式的规则拆分,返回index指定的字符。 hive>select regexp_extract('foothebar', 'foo(.*?)(bar)', 1) from tableName; the hive>select regexp_extract('foothebar', 'foo(.*?)(bar)', 2) from tableName; bar hive>select regexp_extract('foothebar', 'foo(.*?)(bar)', 0) from tableName; foothebar strong>注意,在有些情况下要使用转义字符,下面的等号要用双竖线转义,这是java正则表达式的规则。 select data_field, regexp_extract(data_field,'.*?bgStart\\=([^&]+)',1) as aaa, regexp_extract(data_field,'.*?contentLoaded_headStart\\=([^&]+)',1) as bbb, regexp_extract(data_field,'.*?AppLoad2Req\\=([^&]+)',1) as ccc from pt_nginx_loginlog_st where pt ='2021-03-28' limit 2;
语法: find_in_set(string str, string strList) 返回值: int 说明: 返回str在strlist第一次出现的位置,strlist是用逗号分割的字符串。如果没有找该str字符,则返回0 hive>select find_in_set('ab','ef,ab,de') from tableName; 2 hive>select find_in_set('at','ef,ab,de') from tableName; 0
复合类型构建操作
Map类型构建: map
1 2 3 4 5 6 7
语法: map (key1, value1, key2, value2, …) 说明:根据输入的key和value对构建map类型 hive>Createtable mapTable asselect map('100','tom','200','mary') as t from tableName; hive>describe mapTable; t map<string ,string> hive>select t from tableName; {"100":"tom","200":"mary"}
Struct类型构建: struct
1 2 3 4 5 6 7
语法: struct(val1, val2, val3, …) 说明:根据输入的参数构建结构体struct类型 hive>createtable struct_table asselect struct('tom','mary','tim') as t from tableName; hive>describe struct_table; t struct<col1:string ,col2:string,col3:string> hive>select t from tableName; {"col1":"tom","col2":"mary","col3":"tim"}
array类型构建: array
1 2 3 4 5 6 7
语法: array(val1, val2, …) 说明:根据输入的参数构建数组array类型 hive>createtable arr_table asselectarray("tom","mary","tim") as t from tableName; hive>describe tableName; t array<string> hive>select t from tableName; ["tom","mary","tim"]
复杂类型访问操作
array类型访问: A[n]
1 2 3 4 5 6 7
语法: A[n] 操作类型: A为array类型,n为int类型 说明:返回数组A中的第n个变量值。数组的起始下标为0。比如,A是个值为['foo', 'bar']的数组类型,那么A[0]将返回'foo',而A[1]将返回'bar' hive>createtable arr_table2 asselectarray("tom","mary","tim") as t from tableName; hive>select t[0],t[1] from arr_table2; tom mary tim
map类型访问: M[key]
1 2 3 4 5 6
语法: M[key] 操作类型: M为map类型,key为map中的key值 说明:返回map类型M中,key值为指定值的value值。比如,M是值为{'f'->'foo', 'b'->'bar', 'all'->'foobar'}的map类型,那么M['all']将会返回'foobar' hive>Createtable map_table2 asselect map('100','tom','200','mary') as t from tableName; hive>select t['200'],t['100'] from map_table2; mary tom
struct类型访问: S.x
1 2 3 4 5 6 7 8
语法: S.x 操作类型: S为struct类型 说明:返回结构体S中的x字段。比如,对于结构体struct foobar {int foo, int bar},foobar.foo返回结构体中的foo字段 hive>createtable str_table2 asselect struct('tom','mary','tim') as t from tableName; hive>describe tableName; t struct<col1:string ,col2:string,col3:string> hive>select t.col1,t.col3 from str_table2; tom tim
复杂类型长度统计函数
Map类型长度函数: size(Map<k .V>)
1 2 3 4 5
语法: size(Map<k .V>) 返回值: int 说明: 返回map类型的长度 hive>select size(t) from map_table2; 2
array类型长度函数: size(Array)
1 2 3 4 5
语法: size(Array<T>) 返回值: int 说明: 返回array类型的长度 hive>select size(t) from arr_table2; 4
类型转换函数 ***
1 2 3 4 5 6
类型转换函数: cast 语法: cast(expr as<type>) 返回值: Expected "=" to follow "type" 说明: 返回转换后的数据类型 hive>selectcast('1'asbigint) from tableName; 1
加载数据到hive表当中去 hive (hive_explode)> load data local inpath '/export/servers/hivedatas/explode_json' overwrite intotable explode_lateral_view;
使用explode拆分Array
1
hive (hive_explode)>select explode(split(goods_id,',')) as goods_id from explode_lateral_view;
使用explode拆解Map
1
hive (hive_explode)>select explode(split(area,',')) as area from explode_lateral_view;
拆解json字段
1 2 3 4 5 6 7 8 9 10 11 12
hive (hive_explode)>select explode(split(regexp_replace(regexp_replace(sale_info,'\\[\\{',''),'}]',''),'},\\{')) as sale_info from explode_lateral_view;
然后我们想用get_json_object来获取key为monthSales的数据:
hive (hive_explode)>select get_json_object(explode(split(regexp_replace(regexp_replace(sale_info,'\\[\\{',''),'}]',''),'},\\{')),'$.monthSales') as sale_info from explode_lateral_view;
然后挂了FAILED: SemanticException [Error 10081]: UDTF's are not supported outside the SELECT clause, nor nested in expressions UDTF explode不能写在别的函数内 如果你这么写,想查两个字段,select explode(split(area,',')) as area,good_id from explode_lateral_view; 会报错FAILED: SemanticException 1:40 Only a single expression in the SELECT clause is supported with UDTF's. Error encountered near token 'good_id' 使用UDTF的时候,只支持一个字段,这时候就需要LATERALVIEW出场了
配合LATERAL VIEW使用
配合lateral view查询多个字段
1 2 3
hive (hive_explode)>select goods_id2,sale_info from explode_lateral_view LATERALVIEW explode(split(goods_id,','))goods as goods_id2;
hive (hive_explode)>select goods_id2,sale_info,area2 from explode_lateral_view LATERALVIEW explode(split(goods_id,','))goods as goods_id2 LATERALVIEW explode(split(area,','))area as area2;也是三个表笛卡尔积的结果
最终,我们可以通过下面的句子,把这个json格式的一行数据,完全转换成二维表的方式展现
1
hive (hive_explode)>select get_json_object(concat('{',sale_info_1,'}'),'$.source') as source,get_json_object(concat('{',sale_info_1,'}'),'$.monthSales') as monthSales,get_json_object(concat('{',sale_info_1,'}'),'$.userCount') as monthSales,get_json_object(concat('{',sale_info_1,'}'),'$.score') as monthSales from explode_lateral_view LATERALVIEW explode(split(regexp_replace(regexp_replace(sale_info,'\\[\\{',''),'}]',''),'},\\{'))sale_info as sale_info_1;
node03服务器执行以下命令创建文件,注意数据使用\t进行分割 cd /export/servers/hivedatas vim constellation.txt
数据如下: 孙悟空 白羊座 A 老王 射手座 A 宋宋 白羊座 B 猪八戒 白羊座 A 凤姐 射手座 A
创建hive表并导入数据
1 2 3 4 5 6 7 8 9
创建hive表并加载数据 hive (hive_explode)>createtable person_info( name string, constellation string, blood_type string) row format delimited fields terminated by "\t"; 加载数据 hive (hive_explode)> load data local inpath '/export/servers/hivedatas/constellation.txt'intotable person_info;
按需求查询数据
1 2 3 4 5 6 7 8 9 10 11
hive (hive_explode)>select t1.base, concat_ws('|', collect_set(t1.name)) name from (select name, concat(constellation, "," , blood_type) base from person_info) t1 groupby t1.base;
列转行
所需函数:
EXPLODE(col):将hive一列中复杂的array或者map结构拆分成多行。
LATERAL VIEW
用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
等价于 SELECTmonth,NULL,COUNT(DISTINCT cookieid) AS uv,1AS GROUPING__ID FROM test_t5 GROUPBYmonthUNIONALL SELECTNULLasmonth,day,COUNT(DISTINCT cookieid) AS uv,2AS GROUPING__ID FROM test_t5 GROUPBYday;
再如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
SELECT month, day, COUNT(DISTINCT cookieid) AS uv, GROUPING__ID FROM test_t5 GROUPBYmonth,day GROUPING SETS (month,day,(month,day)) ORDERBY GROUPING__ID;
等价于 SELECTmonth,NULL,COUNT(DISTINCT cookieid) AS uv,1AS GROUPING__ID FROM test_t5 GROUPBYmonth UNIONALL SELECTNULL,day,COUNT(DISTINCT cookieid) AS uv,2AS GROUPING__ID FROM test_t5 GROUPBYday UNIONALL SELECTmonth,day,COUNT(DISTINCT cookieid) AS uv,3AS GROUPING__ID FROM test_t5 GROUPBYmonth,day;
CUBE
根据GROUP BY的维度的所有组合进行聚合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
SELECT month, day, COUNT(DISTINCT cookieid) AS uv, GROUPING__ID FROM test_t5 GROUPBYmonth,day WITHCUBE ORDERBY GROUPING__ID;
等价于 SELECTNULL,NULL,COUNT(DISTINCT cookieid) AS uv,0AS GROUPING__ID FROM test_t5 UNIONALL SELECTmonth,NULL,COUNT(DISTINCT cookieid) AS uv,1AS GROUPING__ID FROM test_t5 GROUPBYmonth UNIONALL SELECTNULL,day,COUNT(DISTINCT cookieid) AS uv,2AS GROUPING__ID FROM test_t5 GROUPBYday UNIONALL SELECTmonth,day,COUNT(DISTINCT cookieid) AS uv,3AS GROUPING__ID FROM test_t5 GROUPBYmonth,day;