hive学习之二:hive sql使用总结及遇到的问题_hive报错is not supported due to overwrite and union
作者:盐析白兔 | 2024-07-20 06:05:24
赞
踩
hive报错is not supported due to overwrite and union all
---------------------------hive sql使用总结-------------------------------------------------
1.hive在连接中不支持不等值连接,不支持or,where条件后不支持子查询。分别举例如下及实现解决办法。
1.1.不支持不等值连接
错误:select * from a inner join b on a.id<>b.id
替代方法:select * from a inner join b on a.id=b.id and a.id is null;
1.2.不支持or
错误:select * from a inner join b on a.id=b.id or a.name=b.name
替代方法:select * from a inner join b on a.id=b.id
union all
select * from a inner join b on a.name=b.name
1.3.where后不支持子查询
错误:select * from a where a.id in (select id from b)
替代方法:select * from a inner join b on a.id=b.id 或in的另外一种高效实现left-semi join
select a.* from a left-semi join b on a.id=b.id a的id在b的id中,但是只能select a表中的字段,不能把b表中的字段查出来。另外right join 和full join
不支持这种写法。
1.4.两个sql union all的字段名必须一样或者列别名要一样。
2.hive不支持where条件后的列别名
错误:select sum(a.amt) as total from a where a.total>20
替代方法:select total from (select sum(a.amt) as total from a) a where total>20
这种方式下例外:select id,count(*) as amt from a where dt='20160101' group by id having amt>1
3.谓词前推
数据量提前过滤,加分区过滤。
4.计算日期间相隔天数,函数datediff要求日期格式为10位,如2012-10-12
5.为了提高hive sql的执行效率可以在执行hql前设置性能参数,只针对当前会话有效。如
set hive.auto.convert.join=false;
set hive.ignore.mapjoin.hint=false;
set hive.exec.parallel=true;
set hive.exec.parallel.thread.number=16;
set hive.groupby.skewindata=true;
set mapred.reduce.tasks=30;
6.按模式匹配字符串取其中的部分。
regexp_extract(a.ed_logo,'(.*)(.0)',1) --字段ed_logo按正则表达式'(.*)(.0)'匹配, 匹配后取第一个部分。如187.0,得187
7.hive排序
row_number() over (distribute by ED_APPLICATION_ID sort by ED_CARD_SEQ desc),按字段ED_APPLICATION_ID分组,按ED_CARD_SEQ降序排序。distribute也可用partition,sort by也可以用
order by。
三种排序及例子:
row_number() ---
rank() |+ distribute by field1 sort by field2 [desc|asc]
dense_rank()----
表结果及值如下:
hive> desc mid;
OK
id string
value string
hive> select * from mid;
OK
1001 12
1001 13
1001 14
1001 12
1002 13
1003 14
1004 15
select *,row_number() over(distribute by id sort by value) as rank from mid;
1001 12 1
1001 12 2
1001 13 3
1001 14 4
1002 13 1
1003 14 1
1004 15 1
row_number()--重复项依然会递增编号
select *,dense_rank() over(distribute by id sort by value) as rank from mid;
1001 12 1
1001 12 1
1001 13 2
1001 14 3
1002 13 1
1003 14 1
1004 15 1
dense_rank()--重复项编号相同
select *,rank() over(partition by id sort by value) as rank from mid;
1001 12 1
1001 12 1
1001 13 3
1001 14 4
1002 13 1
1003 14 1
1004 15 1
rank()----重复项编号相同,但是后续会跳过一个编号。
select id,collect_set(value)[0] from mid group by id;
1001 14
1002 13
1003 14
1004 15
目测去重后从大到小放入集合
select id,collect_list(value)[0] from mid group by id;
1001 12
1002 13
1003 14
1004 15
9.在sql中使用udf,
定义类继承udf类,重写evaluate方法,该方法支持重载,打成jar包,使用如下:
add jar /home/myudf.jar;
create temporary function as myfunction as 'com.comp.udf.UDFClass';
select myfunction(args) from table_name
例子如下:
package com.huateng.spdbccc.mkt24.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
public class FieldLengthFill extends UDF{
/**
* 字段长度填充,如账号acctno,不够10位填充10位,以空格补充
* @param field 要填充的字段名
* @param value 字段值
* @return 填充后的值
*/
public static String evaluate(String field,String value){
if("acctno".equals(field)){
if(value==null){
for(int i=0;i<10;i++){
value = value+" ";
}
return value;
}else if(value.length()<10){
int dis = 10-value.length();
for(int i=0;i<dis;i++){
value = value+" ";
}
}else{
return value;
}
}else if("cardno".equals(field)){
if(value==null){
for(int i=0;i<19;i++){
value = value+" ";
}
return value;
}else if(value.length()<19){
int dis = 19-value.length();
for(int i=0;i<dis;i++){
value = value+" ";
}
}else{
return value;
}
}
return value;
}