我有三张桌子:
- 订单
- OrderId,int PK
- CustomerId, int FK to Customer, NULL 允许
- 顾客
- 客户 ID,int PK
- CompanyId, int FK to Company, NULL 不允许
- 公司
- 公司 ID,int PK
- 名称,nvarchar(50)
我想选择所有订单,无论他们是否有客户,如果他们有客户,那么还有客户的公司名称。
如果我使用这个查询......
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
...它只返回有客户的订单。如果我替换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 报表生成的查询的一小部分。我正在尝试在没有设计器表面的情况下手动编写查询,因为它非常拥挤,并且在进行许多更改后维护查询时遇到问题,并且预计将来会有更多更改。所以,我想以某种方式给查询一个可读的结构。
问题:
- 为什么查询 1 没有按我的预期工作?
- 查询 2 是否是正确的解决方案,尽管(或因为?)它使用了两个 LEFT OTHER JOINS?
- 查询 3 是正确的解决方案吗?
- 有没有更好的方法来编写查询?
- 是否有一些通用的经验法则和实践如何以一种可读的方式编写具有大量外部和内部联接的查询?