INNER JOIN和LEFT / RIGHT OUTER JOIN的问题
我有三个表格:
我想选择所有订单,不管他们是否有客户,如果他们有客户,那么客户的公司名称也是如此。
如果我使用这个查询...
SELECT Orders.OrderId, Customers.CustomerId, Companies.Name
FROM Orders
LEFT OUTER JOIN Customers
ON Orders.CustomerId = Customers.CustomerId
INNER JOIN Companies
OM Customers.CompanyId = Companies.CompanyId
...它只返回有客户的订单。 如果我用LEFT OUTER JOIN
替换INNER JOIN
LEFT OUTER JOIN
...
SELECT Orders.OrderId, Customers.CustomerId, Companies.Name
FROM Orders
LEFT OUTER JOIN Customers
ON Orders.CustomerId = Customers.CustomerId
LEFT OUTER JOIN Companies
OM Customers.CompanyId = Companies.CompanyId
...它可行,但我不明白为什么这是必要的,因为Customers
和Companies
之间的关系是必需的:客户必须有一个公司。
另一种可行的方法似乎是:
SELECT Orders.OrderId, Customers.CustomerId, Companies.Name
FROM Companies
INNER JOIN Customers
ON Companies.CompanyId = Customers.CompanyId
RIGHT OUTER JOIN Orders
OM Customers.CustomerId Orders.CustomerId
此查询具有我期望的内连接和外连接的数量,但问题是难以阅读,因为我的查询是作为查询订单的,因此订单是选择的“根”,而不是公司。 另外RIGHT OUTER JOIN
的使用对我来说也是不熟悉的。
最后一个查询是由设计人员为SQL Server Reporting Services报表生成的查询的一小部分。 我试图在没有设计器表面的情况下手动编写查询,因为它非常拥挤,而且在将来需要进行很多更改和更多更改之后,我仍然遇到问题以维护查询。 所以,我想以某种方式给查询一个可读结构。
问题:
在语义上,连接按照它们出现在from
子句中的顺序进行处理。 (由于SQL优化,它们可能不会按此顺序实际执行,但排序对于定义结果集很重要。)
所以,当你这样做时:
from orders left outer join customers inner join companies
(我要离开了on
条款这些都是为此分心。)
SQL被解释为:
from (orders left outer join customers) inner join companies
你正在做一个inner join
,所以这些值必须出现在两边。 在你的情况下,这撤消了left outer join
的效果。
你要:
from orders left outer join (customers inner join companies)
这里有一些解决方案。
我的首选解决方案是对所有连接使用left outer join
连接。 事实上,为了可读性和可维护性,我写的几乎每个查询都只是left outer join
或[inner] join
连接表。 如果能够以一致的形式编写查询,则必须解析查询以了解连接的语义,这似乎是不必要的努力。
另一种解决方案是使用括号:
from orders left outer join (customers inner join companies)
另一个解决方案是子查询:
from orders left outer join (select . . . from customers inner join companies) cc
INNER JOIN
,所以LEFT JOIN
实际上是一个INNER JOIN
。 RIGHT JOIN
,因为它会让一些开发人员感到困惑,因此不易读。 您通常可以用这种方式编写查询,以便有效使用LEFT JOIN
做同样的事情。 OUTER JOIN
到你的查询,在JOIN
后面也应作为s OUTER JOIN
秒。 否则,您可以排除您不想要的行。 您可以编写像这样嵌套的连接,以便在客户和公司的组合结果上执行左连接,而不是在订单和客户的组合结果上执行内连接。 我基本上只是将你的内连接移动到左外连接的ON子句之前。 其他人建议括号来获得这个结果,如果内存服务的话,两种语法都会导致相同的执行。
SELECT Orders.OrderId, Customers.CustomerId, Companies.Name
FROM Orders
LEFT OUTER JOIN Customers
INNER JOIN Companies
ON Customers.CompanyId = Companies.CompanyId
ON Orders.CustomerId = Customers.CustomerId
链接地址: http://www.djcxy.com/p/86291.html