【问题标题】:Left outer join in BigQuery on multiple keys doesn't if one of them is null如果其中一个为空,BigQuery 中的多个键上的左外连接不会
【发布时间】:2015-09-28 15:30:32
【问题描述】:

我在 BigQuery 中的多个键上的左外连接遇到了一些奇怪的问题。如果其中一个键是右表上的null,则它不匹配,因此它将null 放入右表的所有值中。

如果我有 2 张桌子

   Table1              Table2
------------      ----------------
 k1 |k2  |v3      k1 |k2  | v4
------------      ----------------
 foo|boo |hey     foo|NULL| you
 bar|test|yo      bar|test| hi
 foo|NULL|hey

我做以下加入

SELECT t1.k1, t1.k2, t1.v3, t2.v4 FROM [Table1] t1
LEFT OUTER JOIN EACH [Table2] t2 
ON t1.k1=t2.k1 AND t1.k2=t2.k2

我得到这样的结果

t1_k1|t1_k2|t1_v3|t2_v4
-----------------------
foo  |boo  |hey  |NULL  --No match here so NULL in t2_v4 it's ok
bar  |test |hey  |hi    --It matches here on bar and test
foo  |NULL |hey  |NULL  --It doesn't match on foo NULL.

我希望最后一行是

foo  |NULL |hey  |you

这是预期的行为吗?我的意思是NULL 上没有匹配项。

有没有其他方法可以产生我想要的结果?

【问题讨论】:

标签: google-bigquery


【解决方案1】:

在 SQL 中,NULL 不等于任何东西——甚至它自己。

Gordon's answer 有一些合理的建议,但请注意,BigQuery 仅支持等式连接的连接条件,这排除了ORIS NULL 的使用。

你可以使用除 null 之外的哨兵值吗?例如,如果您将NULL 替换为空字符串(或字符串"null",或其他未出现在数据中的其他内容),则连接将按预期工作。您甚至可以通过使用子查询以最低的性能成本即时执行此操作。

SELECT t1.k1, t1.k2, t1.v3, t2.v4
FROM
  (SELECT IFNULL(k1, "null") k1, IFNULL(k2, "null") k2 FROM [Table1]) t1
LEFT OUTER JOIN EACH
  (SELECT IFNULL(v3, "null") v3, IFNULL(v4, "null") v4 FROM [Table2]) t2
ON t1.k1 = t2.k1 AND t1.k2 = t2.k2

您可以添加外部选择以将字符串 "null" 变回真正的 NULL

显然,这仅在字符串 "null" 未出现在数据中的其他位置时才有效。

【讨论】:

    【解决方案2】:

    这是标准行为。解决它的一种方法是使join 子句更复杂:

    SELECT t1.k1, t1.k2, t1.v3, t2.v4
    FROM [Table1] t1 LEFT OUTER JOIN EACH 
         [Table2] t2 
         ON (t1.k1 = t2.k1 OR (t1.k1 is null and t2.k1 is null)) AND
            (t1.k2 = t2.k2 OR (t1.k2 is null and t2.k2 is null))
    

    这可能会对性能产生不良影响。一些数据库有一个可以使用的空安全相等操作,但我认为 BigQuery 不支持。

    因此,最好的建议是修复数据,使NULL 不是有效的键值。否则,您可以使用多个联接。如果你只有一个 join 键,它看起来像

    SELECT t1.k1, t1.k2, t1.v3, coalesce(t2.v4, t2null.v4)
    FROM [Table1] t1 LEFT OUTER JOIN EACH 
         [Table2] t2 
         ON t1.k1 = t2.k1  LEFT OUTER JOIN EACH
         [Table2] t2null
         ON (t1.k1 is null and t2.k1 is null) ;
    

    但是,对于复合 join 键,这更难组合。

    【讨论】:

      猜你喜欢
      • 2015-03-05
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多