事情是这样的,在使用sparkSQL执行SQL脚本时,遇到如下的情况:
nvl(concat( case WHEN zs.scxs <> 0 THEN concat( '故障发生时:距离上次巡视的时间间隔(平均):' , zs.scxs , '天,') end , case when zs.jscxs <> 0 then concat( '近三次平均巡视时间间隔(平均):' ,zs.jscxs , '天') end), '故障发生时,未开展巡视') zsxs
计算结果表的zsxs字段数据都为‘故障发生时,未开展巡视’,而原表中zs.scxs和zs.jscxs也并不是都等于0,所以很显然是不对的。
后来通过查询相关文档发现,concat函数在MySQL和oracle中的用法是不同的。
Oracle的concat函数只能连接两个字符串,不能多也不能少
select concat('11','22') from test;//1122
MySQL的concat函数可以连接多个字符串,但是在连接字符串的时候,只要其中一个是NULL,那么将返回NULL
select concat('11','22',null);//null
而Oracle的concat函数连接的时候,只要有一个字符串不是NULL,就不会返回NULL
select concat('11',NULL) from dual;//11
concat函数在MySQL和Oracle有如此大的区别,那在sparkSQL中是什么样的呢?通过测试,sparkSQL中的效果与MySQL类似:
还是拿上面的例子,两个case when应该有存在null的情况,concat函数里参数其中一个是NULL,那么将返回NULL,所以最后nvl函数后,得到的结果数据一直都是那段字符串。
使用concat_ws函数替代concat函数。
和concat不同的是, concat_ws函数在执行的时候,不会因为NULL值而返回NULL
select concat_ws(',','11','22','33');//11,22,33 select concat_ws('|','11','22','33');//11|22|33 select concat_ws('*','11','22',NULL);//11*22