我有多个看起来相似的 SQL 查询,其中一个使用
JOIN
,另一个使用 LEFT OUTER JOIN
。我尝试了一下 SQL,发现它返回了相同的结果。代码库可互换地使用 JOIN 和 LEFT OUTER JOIN。虽然 LEFT JOIN
似乎可以与 LEFT OUTER JOIN
互换,但我不能,我似乎无法找到有关 JOIN
的任何信息。这是好的做法吗?
Ex Query1 使用 JOIN
SQL
SELECT
id,
name
FROM
u_users customers
JOIN
t_orders orders
ON orders.status=='PAYMENT PENDING'
例如。使用 LEFT OUTER JOIN 的查询 2
SQL
SELECT
id,
name
FROM
u_users customers
LEFT OUTER JOIN
t_orders orders
ON orders.status=='PAYMENT PENDING'
如前所述:
JOIN 是 INNER JOIN 的同义词。它绝对不同于所有 外连接的类型
所以问题是“我什么时候应该使用外连接?”
这是一篇好文章,有几个很棒的图表:
https://www.sqlshack.com/sql-outer-join-overview-and-examples/
您的问题的简短回答是:
首先是理论:
连接是左连接的子集(所有其他条件相同)。在某些情况下它们是相同的
区别在于,左连接将包括左侧关系中的所有元组(即使它们与连接谓词不匹配),而连接将仅包括与谓词匹配的左侧关系。
例如假设我们必须关系 R 和 S。
假设我们必须对某个谓词 p 执行 R JOIN S(和 R LEFT JOIN S)
J = R 在 (p) 上加入 S
现在,识别 R 中不在 J 中的元组。
最后,将这些元组添加到 J(用 null 填充 J 中不在 R 中的任何属性)
这个结果是左连接:
R 左连接 S (p)
因此,当关系左侧的所有元组都在 JOIN 中时,此结果将与 Left Join 相同。
回到你的问题:
您的 JOIN 很可能包含来自 Users 的所有元组。因此,如果使用 JOIN 或 LEFT JOIN,查询是相同的。
两者完全等价,因为
WHERE
子句将 LEFT JOIN
变成了 INNER JOIN
。
在 LEFT JOIN
中过滤除
first以外的所有表时,条件通常应位于
ON
子句中。想必,您也有一个有效的连接条件,连接两个表:
SELEC id, name
FROM u_users u LEFT JOIN
t_orders o
ON o.user_id = u.user_id AND o.status = 'PAYMENT PENDING';
此版本与
INNER JOIN
版本不同,因为此版本返回 所有用户,甚至那些没有待付款的用户。
两者都是一样的,没有区别。
使用Join时需要使用ON子句。当不使用 ON 子句时,它可以匹配两个表之间的任何数据。 这可能会导致性能问题以及映射不需要的数据。
如果您想查看差异,可以使用“执行计划”。
例如,我使用 Microsoft AdventureWorks 数据库作为示例。
左外连接:
如果你按照你写的那样使用ON子句,就有可能出现循环。 示例“执行计划”如下。
您可以使用 ON 子句补足来访问正确的映射和数据。
select
id,
name
from
u_users customers
left outer join
t_orders orders on customers.id = orders.userid
where orders.status=='payment pending'