这个左连接有什么意义?
What's the point of this left join?
当我使用 BigQuery 查询这两个表时,这个左连接似乎毫无意义。它在 PD.STR_NBR = PI.STR_NBR
上将 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。
这会为您提供 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} 上找不到匹配项。
所以当我在 where 条件中添加时
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
);
假设您有两个 table,农民和 bank_savings,每个 table 都有美国所有此类在世人员的详细信息。
您(美国农村经济部的一名官员)可能 主要 对储蓄账户较低(> 10,000 美元和 < 20,000 美元)的年长农民感兴趣。但您可能也对其他事情感兴趣,例如 (A) 65 岁以上的大面积农民,或者 (B) 任何类型的储蓄账户较低的人。
使用简单的内部 JOIN(可能在 SS 编号上)可以获得主要信息,但不是所有感兴趣的次要数据(例如 A 和 B 数据集)。
仅对于附加数据集 A,我们可以使用 LEFT JOIN。
仅对于附加数据集 B,我们可以使用 RIGHT JOIN。
对于 A 和 B 数据集,我们使用 FULL JOIN。
当然,我们也可以为数据集 A 和 B 设置单独的查询,对每个数据集使用简单的 JOIN。但这会降低效率,尤其是我们要链接到远程数据库 - 政府数据通常就是这种情况。
当我使用 BigQuery 查询这两个表时,这个左连接似乎毫无意义。它在 PD.STR_NBR = PI.STR_NBR
上将 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。
这会为您提供 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} 上找不到匹配项。
所以当我在 where 条件中添加时
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
);
假设您有两个 table,农民和 bank_savings,每个 table 都有美国所有此类在世人员的详细信息。 您(美国农村经济部的一名官员)可能 主要 对储蓄账户较低(> 10,000 美元和 < 20,000 美元)的年长农民感兴趣。但您可能也对其他事情感兴趣,例如 (A) 65 岁以上的大面积农民,或者 (B) 任何类型的储蓄账户较低的人。
使用简单的内部 JOIN(可能在 SS 编号上)可以获得主要信息,但不是所有感兴趣的次要数据(例如 A 和 B 数据集)。 仅对于附加数据集 A,我们可以使用 LEFT JOIN。 仅对于附加数据集 B,我们可以使用 RIGHT JOIN。 对于 A 和 B 数据集,我们使用 FULL JOIN。
当然,我们也可以为数据集 A 和 B 设置单独的查询,对每个数据集使用简单的 JOIN。但这会降低效率,尤其是我们要链接到远程数据库 - 政府数据通常就是这种情况。