SQL INNER JOIN vs LEFT JOIN with WHERE

时间:2016-01-21 20:02:21

标签: sql-server join left-join inner-join

我试图更直观地掌握SQL连接。就在昨天,我了解了如何将RIGHT JOIN重写为LEFT JOIN(通过翻转表的顺序),这有助于我更好地理解两者的连接方式。

然而,现在我想知道是否可以将INNER JOIN重写为带有WHERE条件的LEFT JOIN - 这意味着它们的逻辑可能是等效的(通过“逻辑”我不是指执行计划,而是将描述预期结果集的方式。)

像:

SELECT * FROM HeaderTable
INNER JOIN DetailTable 
ON HeaderTable.ID = DetailTable.ParentID

我将其读作“向我显示表 HeaderTable DetailTable HeaderTable.ID 中具有匹配值的所有记录和 DetailTable.ParentID 字段。“与以下相同:

SELECT * FROM HeaderTable
LEFT JOIN DetailTable 
ON    HeaderTable.ID = DetailTable.ParentID
WHERE HeaderTable.ID = DetailTable.ParentID

我将其读作“向我显示表 HeaderTable DetailTable 中的所有记录,其中 HeaderTable.ID 的值相同作为 DetailTable.ParentID 的值。“

这些会返回相同的结果集吗?我更多地要求逻辑是相同的,而不是一个比另一个更有效。

如果我可能会问,请不要回答任何维恩图,因为这些图似乎没有完全描述加入的逻辑。

3 个答案:

答案 0 :(得分:4)

是的,他们会返回相同的结果。没有where子句的左连接将显示为显示头表中的所有记录和详细信息表中的相关项,如果没有匹配的详细信息,则为null

添加与id相关的where子句可以有效地将左连接转换为内连接,方法是消除那些显示为详细信息部分为null的不匹配行。

在某些数据库(如MS SQL Server)中,左连接将在查询执行计划中显示为内部联接。

虽然你说你不想要维恩图,但我不禁会把你推荐给this question and its answers,即使它们(我认为非常有用)维恩图也充满了。

答案 1 :(得分:1)

是的,他们会返回相同的结果。

但是你可以简单地写

SELECT * 
FROM HeaderTable, DetailTable
WHERE HeaderTable.ID = DetailTable.ParentID

这也会返回相同的结果。这是在引入join-clause之前使用的旧语法。

答案 2 :(得分:0)

如果你在左边的连接中引用了左边的连接,那么你将左边的内部取消并将其转换为常规连接