这种左联接的意义何在?

时间:2018-07-05 17:54:19

标签: sql google-bigquery teradata

当我使用BigQuery查询这两个表时,这种左联接似乎毫无意义。它在PD.STR_NBR = PI.STR_NBR上将PD加入PD到PI中,然后按PD.STR_NBR IS NULL进行过滤。

SELECT
      PI.CUST_ORD_NBR AS CUST_ORD_NBR,
      PI.STR_NBR AS STR_NBR,
      PI.SKU_NBR AS SKU_NBR
FROM
      PURCH_ITEM_ID PI
LEFT JOIN
      PROF_BID_DTL_W7 PD
   ON PD.CUST_ORD_NBR = PI.CUST_ORD_NBR
  AND PD.STR_NBR = PI.STR_NBR -- checks equality
  AND CAST(PD.SKU_NBR AS STRING) = PI.SKU_NBR
WHERE PD.STR_NBR IS NULL -- filters by null
;

我不知道它是否相关,但是我会提到此BQ代码已从Teradata sql过渡而来。

2 个答案:

答案 0 :(得分:5)

这将为您提供所有记录,其中包含str_nbr,CUST_ORD_NBR和skus的组合,这些记录存在于PURCH_ITEM_ID中,但不包含PROF_BID_DTL_W7

编辑:RToyo在评论中发表了很好的解释。

仅出于完整性考虑。举个例子

TableA

Key      Value
1        A
2        B
3        C

TableB
Key      Value
1        A
2        B

WHERE子句适用于中间结果集。

所以,如果我加入

SELECT *
  FROM TableA A
  LEFT
  JOIN TableB B
    ON A.Key = B.Key
   AND A.Value = B.Value

结果集将是

Key Value Key   Value 
1   A     1     A
2   B     2     B
3   C     NULL  NULL

因为在{3,C}上找不到匹配项。

所以当我在其中添加条件

SELECT TableA.*
  FROM TableA A
  LEFT
  JOIN TableB B
    ON A.Key = B.Key
   AND A.Value = B.Value
 WHERE B.Key IS NULL

我刚得到最后一条记录

Key Value 
3   C

这在逻辑上(并且通常由优化程序以相同的方式实现)等同于

SELECT TA.*
  FROM TableA TA
 WHERE NOT EXISTS
         ( SELECT 1
             FROM TableB TB
            WHERE TA.key = TB.key
              AND TA.value = TB.value
         );

答案 1 :(得分:0)

假设您有两个表,农民表和银行储蓄表,每个表都包含美国所有此类居住者的详细信息。 您(美国农村经济部的一位官员)可能对储蓄帐户低(> 10,000美元和<20,000美元)的老年农民主要感兴趣。但是您可能还对其他事物感兴趣,例如(A)种植面积超过65岁的农民,或者(B)储蓄账户低的任何人。

使用简单的内部JOIN(也许在SS号上)可以获取主要信息,但不能获取所有感兴趣的辅助数据(例如A和B数据集)。 仅对于其他数据集A,我们可以使用LEFT JOIN。 仅对于其他数据集B,我们可以使用RIGHT JOIN。 对于A和B数据集,我们都使用FULL JOIN。

当然,我们也可以使用简单的JOIN为数据集A和B设置单独的查询。但这会降低效率,特别是我们正在链接到远程保存的数据库-政府数据通常是这种情况。