SQL加入CASE和WHERE

时间:2009-07-31 13:45:40

标签: sql sql-server

我有三个表 - 一个用于运费,一个用于产品,一个用于特定产品的运费率例外。运费如下: 每种产品都有运费,但这个价格可以被例外覆盖。如果产品不存在例外,则默认费率用于用户选择的运费。 alt text http://mi6.nu/sqljoin.png 我正在尝试加入这些表,以便如果存在例外,则选择该价格,否则,选择默认价格但我遇到了加入问题。我需要按产品ID查询,我有(第2行用于调试)

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语句,但我需要先返回数据。

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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回答推荐的那样,对于一个简单的表达式,虽然案例可行,但您不需要案例陈述,Coalesce就足够了:

 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

答案 2 :(得分:1)

如果您使用MSSQL,COALESCE功能会有所帮助。它首先返回not-null。

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

对案例做同样的事情......时:

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

希望这会有所帮助..

答案 3 :(得分: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