是否确实必须在SQL查询中的左联接之后的所有联接也都是左联接?为什么或者为什么不?

时间:2018-12-13 16:32:52

标签: sql

我记得大学时代的经验法则,如果在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

2 个答案:

答案 0 :(得分:3)

不是他们一定是。它们应该是(或者最后应该是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中没有匹配的记录。第二个问:“我必须有匹配的分类帐记录。”因此,{{1 }}将第一个转换为inner join

由于您大概希望所有客户,无论其他两个表中是否存在匹配项,都应使用inner join

left join

答案 1 :(得分: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是首先创建的,然后按顺序联接(您可以想象它是因为2个表再次联接)