2009-07-31 45 views
2

我有三張表 - 一個用於運費,一個用於產品,一個用於特殊產品運費的例外情況。運費如下收取: 每件產品都有運費,但這個價格可以被例外覆蓋。如果產品不存在例外情況,則默認費率用於用戶選擇的運費。 alt text http://mi6.nu/sqljoin.png 我試圖加入這些表,以便如果存在異常,則選擇該價格,否則,默認價格被選中,但我遇到了連接問題。我需要通過產品ID來查詢的,我有(2號線是爲了調試)SQL加入CASE和WHERE

SELECT r.ID AS ShippingRateID, r.Name, 
e.*, r.* 
FROM shipping r LEFT JOIN shippingexceptions e ON r.ID = e.ShippingRateID 
WHERE e.ProductID = 48 

,我需要回到:

1 Uk and Northern Ireland 1 
2 EU Eire...  10 
3 US and Canada  2.16 
4 Rest of world  2.44 

所以,如果有異常存在,則使用異常的價格,否則使用默認價格。我打算使用CASE語句,但我需要首先返回數據。

+0

什麼是你的問題? – hobodave 2009-07-31 13:52:41

回答

4

我注意到的第一件事是,你必須在表E的謂詞條件,它位於外連接的「外」側。這將立即將聯接轉換爲內部聯接,因爲在內部存在記錄但外部沒有記錄的情況下,通常會生成的行將在外部表中的列中產生空值執行where子句謂詞(WHERE e.ProductID = 48)。

您需要將此謂詞放入連接條件中。
這樣的:

SELECT r.ID AS ShippingRateID, r.Name, e.*, r.* 
FROM shipping r 
    LEFT JOIN shippingexceptions e 
     ON r.ID = e.ShippingRateID 
      And e.ProductID = 48 

接下來,Joels答案建議,對於簡單的表達,雖然情況會工作,你不需要一個case語句,合併就足夠了:

SELECT r.ID AS ShippingRateID, r.Name, 
    Coalesce(e.rate, defaultrate) as Rate, 
    e.*, r.* 
FROM shipping r 
    LEFT JOIN shippingexceptions e 
     ON r.ID = e.ShippingRateID 
      And e.ProductID = 48 
8

爲什麼不使用聚結

SELECT r.ID AS ShippingRateID, r.Name, coalesce(e.cost, r.defaultprice) 
FROM shipping r LEFT JOIN shippingexceptions e ON r.ID = e.ShippingRateID 
WHERE e.ProductID = 48 

這樣,如果e.rate爲null,則使用r.rate。

你也應該把你的e.ProductId的加入,因此不會強迫你只選擇產品例外

SELECT r.ID AS ShippingRateID, r.Name, coalesce(e.cost, r.defaultprice) 
FROM shipping r LEFT JOIN shippingexceptions e ON r.ID = e.ShippingRateID and e.ProductID = 48 
+0

合併的一個「l」 - 不是兩個。否則是一個很好的迴應,關於WHERE子句是非常好的一點;我沒有注意到OP已經做到了。 – 2009-07-31 13:55:39

+0

嘿,謝謝。我是一名程序員,而不是英語專業。我通常依賴於那些東西的語法檢查器和編譯器。;) – Joel 2009-07-31 13:58:27

0
SELECT COALESCE(
     (
     SELECT TOP 1 cost 
     FROM shippingexceptions se 
     WHERE se.ShippingRateID = r.id 
       AND se.ProductID = 48 
     ), DefaultPrice 
     ) AS price 
FROM shipping r 

,或者SQL Server 2005+

SELECT COALESCE(cost, DefaultPrice) AS price 
FROM shipping r 
OUTER APPLY 
     (
     SELECT TOP 1 cost 
     FROM shippingexceptions 
     WHERE ShippingRateID = r.id 
       AND ProductID = 48 
     ) se 
1

如果你是MSSQL,CO ALESCE功能會有所幫助。它首先返回非空。

是, select COALESCE(shippingexceptions.Rate, shipping.Rate)

做同樣的事情的情況下..當:

Select Case when shippingexceptions.Rate is not null THEN shippingexceptions.Rate 
ELSE shipping.Rate 

希望這有助於..