【问题标题】:Hive: Optimal way to JOIN using 2 ON conditions with NULLHive:使用 NULL 的 2 个 ON 条件进行 JOIN 的最佳方式
【发布时间】:2019-12-25 00:45:21
【问题描述】:

我有 2 个表格,如下所示。

表_A

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

表_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));

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

【问题讨论】:

  • 尝试使用COALESCE作为ID字段来改变NULL的非空值:ON COALESCE(A.ID1, '_NULL_') = COALESCE(B.ID1, '_NULL_') AND ...

标签: join hive left-join hiveql


【解决方案1】:

要像普通值一样连接 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);

【讨论】:

    【解决方案2】:

    Hive 不支持 on 条件中的 or 表达式。
    连接条件应包含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')
    

    【讨论】:

      【解决方案3】:

      这是一个典型的案例场景,它需要一个 NULL 安全的相等运算符,它由 Hive 原生支持,带有 GenericUDF <=>。正如我所引用的,这个运算符:

      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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-03
        • 2016-10-09
        • 1970-01-01
        • 1970-01-01
        • 2017-08-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多