Spark自动类型转换导致的坑

在开发中,遇到了一个奇怪的join结果。简化之后的模型如下,脑机执行的结果第一个为true,第二个为false,而实际的结果却是两个True。

1
2
3
4
5
6
7
8
9
10
11
create or replace temp view test1 as
select
'23843968833490313' as s1
, cast('23843968833490313' as decimal(18,0)) as s2
, cast('23843968833490312' as decimal(18,0)) as s4
;
select
s1 = s2
, s1 = s4
from test1
;

究其原因是在不同类型的比较中,spark会把其先转为Double类型再进行比较,而Double类型的精度有限,这样就会出现让人匪夷所思的现象。在实际复杂的join中,往往会忽视数据类型的检查。

所以在实际开发中,一定要保证join两边的数据类型一致,特别是join条件两边存在表达式的情况,例如:

1
2
3
4
from tableA 
left join tableB
on coalesce(tableA.id1 , tableA.id2) = tableB.id
;

建议写成:

1
2
3
4
from tableA 
left join tableB
on cast(coalesce(tableA.id1 , tableA.id2) AS decmial(18,0)) = tableB.id
;

在有表达式的地方,加上显式类型转换可以避免此。