2009-07-31 74 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 

希望这有助于..