如何构造sql查询来处理多个子表

时间:2012-06-15 02:31:51

标签: sql sql-server tsql sql-server-2005

我需要有关如何编写SQL Server 2005查询来处理连接多个子表的帮助。这是我的情景:

表:

客户

  • Customer_PK

订单

  • Order_PK
  • OrdersTypeA_FK
  • OrdersTypeB_FK
  • OrdersTypeC_FK
  • Customer_FK

OrdersTypeA

  • OrdersTypeA_PK
  • Shipper_FK

OrdersTypeB

  • OrdersTypeB_PK
  • Shipper_FK

OrdersTypeC

  • OrdersTypeC_PK
  • Shipper_FK

托运人

  • Shipper_PK
  • ShipperAddress_FK

ShipperAddress

  • ShipperAddress_PK
  • ShipperState

Orders表的数据如下所示:

Order_PK   OrdersTypeA_FK    OrdersTypeB_FK    OrdersTypeC_FK    Customer_FK
--------   --------------    --------------    --------------    -----------
1          1                 null              null              1
2          null              1                 null              2
3          null              null              1                 3

我的问题是我需要让select join语句通过从三个OrdersType表中的一个中查找Shipper_FK来检索ShipperAddress。 Orders表每行只有一个OrdersType FK。我需要从OrdersType表中检索的唯一内容是Shipper_FK,以便我可以加入ShipperAddress表。

那么联接怎么看?

select 
ShipperAddress.ShipperState 
from Customers
left join Orders on Orders.Customer_FK = Customers.Customer_PK

????????

left join Shippers on Shipper_PK = ??????.Shipper_FK
left join ShipperAddress on ShipperAddress.ShipperAddress_PK = Shippers.ShipperAddress_FK

我无法为每个OrdersType表单独连接到ShipperAddress。这是一个较小的问题样本,在OrdersType级别有更多表。 Shipper_FK在每个OrdersType表中都是相同的。我需要访问Shipper_FK,无论它来自哪个OrdersType表来继续使用join语句。怎么办?

1 个答案:

答案 0 :(得分:1)

阅读,优化和维护这将会很有趣......

SELECT sa.ShipperState  --, other columns surely
FROM dbo.Customers AS c
LEFT OUTER JOIN dbo.Orders AS o 
ON o.Customer_FK = c.Customer_PK
LEFT OUTER JOIN dbo.OrdersTypeA AS oa
  ON oa.OrdersTypeA_PK = o.OrdersTypeA_FK
LEFT OUTER JOIN dbo.OrdersTypeB AS ob
  ON ob.OrdersTypeB_PK = o.OrdersTypeB_FK
LEFT OUTER JOIN dbo.OrdersTypeC AS oc
  ON oc.OrdersTypeC_PK = o.OrdersTypeC_FK
LEFT OUTER JOIN dbo.Shippers AS s
  ON s.Shipper_PK = COALESCE(oa.Shipper_FK, ob.Shipper_FK, oc.Shipper_FK)
LEFT OUTER JOIN dbo.ShipperAddress AS sa
  ON s.ShipperAddress_FK = sa.ShipperAddress_PK;