这个左联盟有什么意义?

Eri*_*ric 0 sql teradata google-bigquery

当我使用BigQuery查询这两个表时,似乎这个左连接是没有意义的.它将PD连接到PI上PD.STR_NBR = PI.STR_NBR,然后过滤掉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
;
Run Code Online (Sandbox Code Playgroud)

我不知道它是否相关,但我会提到这个BQ代码已经从Teradata sql过渡了.

Err*_*646 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
Run Code Online (Sandbox Code Playgroud)

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

所以,如果我加入

SELECT *
  FROM TableA A
  LEFT
  JOIN TableB B
    ON A.Key = B.Key
   AND A.Value = B.Value
Run Code Online (Sandbox Code Playgroud)

结果集将是

Key Value Key   Value 
1   A     1     A
2   B     2     B
3   C     NULL  NULL
Run Code Online (Sandbox Code Playgroud)

因为在{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
Run Code Online (Sandbox Code Playgroud)

我刚拿到最后一张唱片

Key Value 
3   C
Run Code Online (Sandbox Code Playgroud)

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

SELECT TA.*
  FROM TableA TA
 WHERE NOT EXISTS
         ( SELECT 1
             FROM TableB TB
            WHERE TA.key = TB.key
              AND TA.value = TB.value
         );
Run Code Online (Sandbox Code Playgroud)

  • 我现在意识到这相当于一个排除左连接(左中):https://www.codeproject.com/KB/database/Visual_SQL_Joins/Visual_SQL_JOINS_orig.jpg (2认同)