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语句翻译过程中总结的主要内容,如果未能解决你的问题,请参考以下文章

Impala性能优化总结

Impala vs SparkSQL:内置函数翻译:fnv_hash

Impala 单个插入语句创建多个文件

交互式查询工具——Impala

Impala 中 SELECT 语句的算术运算

Impala在腾讯金融大数据场景中的应用