impala语句翻译过程中总结
Posted 繁星杂论
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了impala语句翻译过程中总结相关的知识,希望对你有一定的参考价值。
将td数据库中sql语句翻译修改成impala中执行语句时遇到的问题汇总:
在工作中需要把在td数据库中执行的SQL语句修改,在保证逻辑不变的情况下进行修改使得在大数据平台impala中能执行通过。在过程中由于语法函数有差异,遇到不少问题浪费很多时间精力,这里挑主要的汇总记录下来,以便以后参考;
1、关于日期函数:
日期转换:
原来语句是cast('20170930' as date format 'yyyymmdd')
修改后是:cast('2017-09-30' as timestamp) 显示格式是2017-09-30 00:00:00
注意转换的时候格式要是2017-09-30格式,否则结果为NULL
在impala中date-1不能执行
select a.* from table_name a
inner join testdb.table1 b on a.cad_no=b.cad_id
and b.st_dt <= date-1
and b.ed_dt> date-1
这里的date-1需要换成adddate(now(),-1)才可以执行。
在impala中last_day不能执行,在hive中是有last_day函数的。
原语句:last_day(add_months(date,-1))
这句结果是返回上月末。
在hive中执行的时候需要修改为:last_day(add_months(current_date,-1)) 结果格式为:2018-02-28
在impala中需要修改为:to_date(trunc(now(),'mm')-interval 1 day) 结果2018-02-28类型为string,
或者是:adddate(to_date(trunc(now(),'mm')),-1) 结果2018-02-28 00:00:00 类型为timestamp
2、在impala中数值比较或运算的过程中,注意两边的类型要一致,比如timestamp类型就不能和string类型的日期比较。
3、在impala中没有index函数:
比如原语句是
case when bank_name like '%银行%' then substr(bank_name,index(bank_name,'银行')-4,8) end
这里index表示返回字符在字符串中出现的位置,所以这里index换成instr,效果相同。但是这里尝试过,在hive中得出的结果是正常的,在impala中执行的时候结果是乱码。这个问题还需注意。
4、在impala中case when 语句中若有any语句的时候也是报错。
比如:case when bank_name like any ('%中国银行%' or '%中国%') then '都是银行' end
这里在impala中报错无法执行,这里我的解决办法是把这句拆开写:
case when bank_name like '%中国银行%' then '都是银行'
when bank_name like '%中国%' then '都是银行' end
5、对于字符串截取函数substr;
在impala中substr截取的类型一定是字符串。
比如:substr(cast(txn_dt as timestamp),1,6) 在原语句中txn_dt实际就是timestamp类型。这句在hive中是可以执行的,但是在impala中必须把txn_dt转换为string类型才能执行。substr(cast(txn_dt as string),1,6)
但是注意:我在执行过程中发现substr在impala中执行的时候结果也会是乱码,在hive中执行的结果是正常的,这个问题还需要解答。
6、qualify row_number():
在impala翻译过程中也有遇到语句是qualify row_number()这种语句,这种语句在hive和impala中都没法执行下去,这里修改的时候改写成嵌套的形式就可以执行。
比如原语句:
create table if not exists testdb.table_name as(
select id,name,row_number() over(partition by id order by count(name) desc) as rank_
from testdb.table1
qualify row_number () over(partition by id order by count(name) desc) <= 3
group by 1,2
);
改写成嵌套形式:
create table if not exists testdb.table_name as(
select a.* from (
select id,name,row_number() over(partition by id order by count(name) desc) as rank_
from testdb.table1
group by 1,2
) a
where a.rank_ <= 3
);
7、在impala中不支持在同一个查询中有连续多个count()语句。
在impala中没有事物的概念,不支持commit,rollback等,没有update,没有delete。
在impala中对于子查询必须使用别名,如果对于查询中的一个表达式使用了别名,那么这个别名在同一个查询列表中不能重复出现,这里有一个解决办法是将表达式重复编码,还有一种方式是改写成嵌套形式。
8、在impala中同一个语句中distinct和group by会冲突不能执行下去,在hive中也是不能执行下去,
就比如:select distinct id,name from testdb.name group by 1;
这样的语句在td数据库中可以执行,但在hive和impala中有报错,从逻辑上来说group by的时候就有去重的作用,这里distinct可以去掉,如果有要求一定要保留,那么改写成嵌套的形式或者是建临时表。
9、impala中可以对多种文件格式进行查询。impala基本上只能进行查询操作,无法写入数据,要写入数据的时候就通过hive进行。在hive对数据进行创建删除修改等操作的时候,impala无法自动识别元数据变更的情况,所以就需要执行命令invalidate metadata进行更新元数据,通过hive插入加载等改变数据的时候,impala也是不能自动识别出数据的变动,这时候还可以进行refresh table 操作。
10、内存溢出
还有一种内存溢出的报错:memory limit exceeded.
这种解决办法还没有具体实现,还需要研究。
以上是关于impala语句翻译过程中总结的主要内容,如果未能解决你的问题,请参考以下文章