SQL查询中左连接之后的所有连接是不是也必须是左连接?为啥或者为啥不?
Posted
技术标签:
【中文标题】SQL查询中左连接之后的所有连接是不是也必须是左连接?为啥或者为啥不?【英文标题】:Is it true that all joins following a left join in a SQL query must also be left joins? Why or why not?SQL查询中左连接之后的所有连接是否也必须是左连接?为什么或者为什么不? 【发布时间】:2018-12-13 16:32:51 【问题描述】:我记得大学时的一条经验法则,如果您在 SQL 查询中放置左连接,那么该查询中的所有后续连接也必须是左连接而不是内连接,否则您会得到意想不到的结果.但我不记得这些结果是什么,所以我想知道我是否记错了什么。任何人都可以支持我或反驳它吗?谢谢! :)
例如:
select * from customer
left join ledger on customer.id= ledger.customerid
inner join order on ledger.orderid = order.id -- this inner join might be bad mojo
【问题讨论】:
您最好告诉我们您使用的是什么 RDBMS,因为它们在允许和不允许的方面有所不同。 “意外结果”对我来说似乎很可疑,但它很可能再次取决于(而且几乎肯定是)数据库。 我主要使用 SQL Server。 "...否则您会得到意想不到的结果...":除非您知道自己在做什么,并且会给出结果做期待。 【参考方案1】:不是他们必须是。他们应该是(或者最后可能是full join
)。这是编写查询和表达逻辑的更安全的方式。
您的查询是:
select *
from customer c left join
ledger l
on c.id = l.customerid inner join
order o
on l.orderid = o.id
left join
说“保留所有客户,即使 ledger
中没有匹配记录。第二个说,“我必须有一个匹配的分类帐记录”。所以,inner join
将第一个转换为inner join
。
因为您大概想要所有客户,无论其他两个表中是否存在匹配项,您都将使用left join
:
select *
from customer c left join
ledger l
on c.id = l.customerid left join
order o
on l.orderid = o.id
【讨论】:
【参考方案2】:你没记错其中的某些部分!
问题是,当您像这样链接连接表时
select * from customer
left join ledger on customer.id= ledger.customerid
inner join order on ledger.orderid = order.id
JOIN 是按顺序执行的,所以当customer left join ledger
发生时,您要确保所有来自客户返回的连接键(因为它是左连接!并且您将客户放置在左侧)。
接下来,
前 JOIN 的结果与 order
连接(使用内部连接),强制“第一个连接键”与来自 order
的键匹配(1 到 1),所以你最终只会得到order
表中也匹配的记录
坏魔力?这实际上取决于您要完成的工作。
如果你想保证来自customers
的所有记录都返回,你应该保持“左加入”它。
但是,您可以通过以下方式使其更直观地理解(不一定是更好的 SQL 编写方式!):
SELECT * FROM
(
(SELECT * from customer) c
LEFT JOIN
(SELECT * from ledger) l
ON
c.id= l.customerid
) c_and_l
INNER JOIN (OR PERHAPS LEFT JOIN)
(SELECT * FROM order) as o
ON c_and_l.orderid (better use c_and_l.id as you want to refer to customerid from customers table) = o.id
所以现在你明白了 c_and_l 是先创建的,然后加入到 order 中(你可以把它想象成 2 个表再次加入)
【讨论】:
以上是关于SQL查询中左连接之后的所有连接是不是也必须是左连接?为啥或者为啥不?的主要内容,如果未能解决你的问题,请参考以下文章