2012-06-15 32 views
0

我需要編寫SQL Server 2005查詢來處理連接多個子表的幫助。這是我的情景:如何構造tsql查詢以處理多個子表

表:

客戶

  • 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 

我的問題是,我需要通過從三個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 

我不能有一個單獨的連接到ShipperAddress每個OrdersType表。這是在OrdersType級別有更多表的問題的較小示例。 Shipper_FK在每個OrdersType表中都是相同的。無論來自何處的OrdersType表繼續加入聲明,我都需要獲取Shipper_FK。如何做到這一點?

+0

你爲什麼有三種不同的訂單類型的列(後三個不同的表跟他們一起去)?這些訂單類型有什麼不同,需要分別建模? –

+0

這只是我正在處理的表結構的一個例子。對於此示例,請將OrderType_A視爲郵件類型,將OrderType_B視爲Internet類型,將OrderType_C視爲電話類型。表格結構已設置,無法更改。這裏的問題是弄清楚如何編寫查詢。 – user31673

回答

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;