2013-03-20 94 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