配置单元:在空条件下使用2连接的最佳方式

iyr7buue  于 2021-06-25  发布在  Hive
关注(0)|答案(3)|浏览(300)

我有两张table,如下所示。
表a

ID1  ID2  NAME
112  NULL ADAM
132  990  BRIAN
NULL 980  CARL

表\u b

ID1  ID2  SURNAME
112  NULL LEVINE
132  990  LARA
NULL 980  JOHNSON

如果我按下面的方式加入表,空比较将不起作用,因此不会返回adam的姓氏

SELECT A.NAME,B.SURNAME
FROM
TABLE_A A
LEFT JOIN
TABLE_B B
ON A.ID1 = B.ID1
AND
A.ID2 = B.ID2;

我在id2的on子句中添加了一个null检查,它确实起了作用,但对于小表来说,该操作的代价也很高((见下文)

SELECT A.NAME,B.SURNAME
FROM
TABLE_A A
LEFT JOIN
TABLE_B B
ON 
(A.ID1 = B.ID1 OR (A.ID1 IS NULL AND B.ID1 IS NULL))
AND
(A.ID2 = B.ID2 OR (A.ID2 IS NULL AND B.ID2 IS NULL));

进行这种比较的正确方法是什么?

vlju58qv

vlju58qv1#

这是一个典型的案例场景,它调用空安全的相等运算符,这个运算符本机由带有genericudf的hive支持 <=> . 这个操作员,如我所引用的:

Returns same result with EQUAL(=) operator for non-null operands, 
but returns TRUE if both are NULL, FALSE if one of the them is NULL.

因此,sql非常简单,如下所示:

select 
    a.name,
    b.surname
from table_a a
left join table_b b
on a.id1 <=> b.id1 and a.id2 <=> b.id2;
yv5phkfx

yv5phkfx2#

要像普通值一样连接null,请使用 NVL() 要替换的函数 NULL 例如,数据中通常不使用的值 -9999 :

SELECT A.NAME,B.SURNAME
FROM
TABLE_A A
LEFT JOIN
TABLE_B B
ON NVL(A.ID1,-9999) = NVL(B.ID1,-9999)
AND
NVL(A.ID2,-9999) = NVL(B.ID2,-9999);
eaf3rand

eaf3rand3#

Hive不支持 or 中的表达式 on 条件。
联接条件应包括 purely equality expression .
我更喜欢 COALESCE 功能:

SELECT A.NAME,B.SURNAME
FROM
TABLE_A A
LEFT JOIN
TABLE_B B
ON 
 COALESCE(A.ID1, 'missing') = COALESCE(B.ID1, 'missing') 
AND
 COALESCE(A.ID2, 'missing') = COALESCE(B.ID2, 'missing')

相关问题