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查询中左连接之后的所有连接是不是也必须是左连接?为啥或者为啥不?的主要内容,如果未能解决你的问题,请参考以下文章

SQL:左连接,右连接是啥概念啊

SQL:左连接,右连接是啥概念啊

SQL 内连接到左连接表

LINQ中左外连接的等价物[重复]

Spark数据框左连接应在右侧添加默认行而不是null的连接

什么是左外连接 SQLserver