2013-03-20 85 views
1

我有一個從表中選擇產品的查詢。產品可以有多個價格(考慮各種價格)和默認價格。SQL中的互斥值

當然,這是一對多的關係。我需要選擇具有給定價格或默認價格的產品 - 這意味着相互排斥。我知道這可以通過單獨的查詢和WHERE(NOT)IN子句或union聲明來完成,但我確信一個更優化的方式必須是可能的。我的查詢目前看起來是這樣的:

SELECT products.*, products_prices.price 
FROM products RIGHT JOIN 
    products_prices ON (products.id = products_prices.productId) 
WHERE products_prices.businessId = ? 
OR products_prices.businessId IS NULL // this needs to become mutual. 

編輯:我結束了使用此查詢,這是戈登·利諾夫的一個稍作修改的版本:

SELECT distinct p.*, coalesce(pp.price, defpp.price) 
FROM products p LEFT JOIN 
     products_prices pp 
     ON p.id = pp.productId and pp.businessId = ? left join 
     products_prices defpp 
     on p.id = defpp.productId and defpp.businessId is NULL 
+0

不,我不明白。也許一個例子會說明問題。 – Strawberry 2013-03-20 14:19:10

+0

你說「給定價格」,但價格似乎不是一個參數..除非'businessId'是價格? – 2013-03-20 14:20:49

+0

對不起,你說得對,沒有給出價格。我的意思是說,具有不爲NULL的businessId的產品記錄優先於不具有重複性的產品(考慮到有一個businessId對每個產品都爲NULL的記錄) – QuintenVK 2013-03-20 14:27:16

回答

7

如果我正確理解你的問題,products表將具有默認價格並且product_prices表將具有任何其他價格。

您想知道默認價格在哪裏使用,這意味着沒有其他價格。爲此,使用left outer join

SELECT p.*, coalesce(pp.price, p.default_price) 
FROM products p LEFT OUTER JOIN 
    products_prices pp 
    ON p.id = pp.productId 
WHERE pp.price = GIVENPRICE or pp.price is null 

基於您的評論,您存儲與商家ID爲NULL記錄的默認價格。在這種情況下,我會對價格表執行兩個連接:

SELECT p.*, coalesce(pp.price, defpp.price) 
FROM products p LEFT OUTER JOIN 
    products_prices pp 
    ON p.id = pp.productId and pp.price = GIVENPRICE left outer join 
    products_prices defpp 
    on p.id = defpp.productId and defpp.businessId is NULL 

第一個連接獲取與給定價格匹配的價格。第二個獲得默認價格。如果有第一個結果,則使用第二個結果,否則使用第二個結果。

+0

恐怕這是錯誤的。由於附加參數,默認價格位於products_prices表中,但默認價格都具有NULL的businessId。 – QuintenVK 2013-03-20 14:24:25

+0

美麗的解決方案 – 2013-03-20 14:24:39

+0

當然,第二個查詢中的where子句是多餘的? – 2013-03-20 14:38:15