SQL CASE返回错误的值

时间:2016-08-26 19:50:37

标签: sql sql-server case

我编写了以下查询,但CASE语句返回的值不正确。当soaddr有一个值而不是从soaddr返回值时,它将从arcust返回不正确的值。但是,如果我更改else语句以从soaddr中提取值,那么它将返回NULL值。我做错了什么?

SELECT DISTINCT a.custno, b.company,
    CASE WHEN c.address1 = NULL THEN b.address1
    ELSE b.address1
    END as address,
    CASE WHEN c.city = NULL THEN b.city
    ELSE b.city
    END as city,
    CASE WHEN c.addrstate = NULL THEN b.addrstate
    ELSE b.addrstate
    END as addrstate,
    CASE WHEN c.zip = NULL THEN b.zip
    ELSE b.zip
    END as zip,
    invno, descrip, qtyshp, price, extprice, b.tax, invdte 
FROM artran a
LEFT JOIN arcust b ON a.custno = b.custno
LEFT JOIN soaddr c ON a.custno = c.custno

2 个答案:

答案 0 :(得分:3)

您无法将值与NULL进行比较。 使用为null。

CASE WHEN c.address1 IS NULL THEN b.address1
 ELSE b.address1

答案 1 :(得分:2)

它返回错误值的原因是你的case语句被设置为总是返回arcust值,因为THEN&的所有部分都是如此。 ELSE引用指向arcust的b表别名。介于那之间并正确地比较null,因为@ServerSentinel恰当地指出你没有得到你想要的结果。按如下所示修改查询以指向c表别名,并将null与IS NULL进行比较

SELECT DISTINCT a.custno, b.company,
    CASE WHEN c.address1 IS NULL THEN b.address1
    ELSE c.address1
    END as address,
    CASE WHEN c.city IS NULL THEN b.city
    ELSE c.city
    END as city,
    CASE WHEN c.addrstate IS NULL THEN b.addrstate
    ELSE c.addrstate
    END as addrstate,
    CASE WHEN c.zip IS NULL THEN b.zip
    ELSE c.zip
    END as zip,
    invno, descrip, qtyshp, price, extprice, b.tax, invdte 
FROM artran a
LEFT JOIN arcust b ON a.custno = b.custno
LEFT JOIN soaddr c ON a.custno = c.custno

接下来学习COALESCE()对你来说是一个很大的帮助,因为它基本上为你写了case语句并返回第一个非null值。所以你可以写一下:

SELECT DISTINCT a.custno, b.company,
    COALESCE(c.address1,b.address1) as address,
    COALESCE(c.city,b.city) as city,
    COALESCE(c.addrstate,b.addrstate) as addrstate,
    COALESCE(c.zip,b.zip) as zip,
    invno, descrip, qtyshp, price, extprice, b.tax, invdte 
FROM artran a
LEFT JOIN arcust b ON a.custno = b.custno
LEFT JOIN soaddr c ON a.custno = c.custno

如果它不为null,那么它将为你提供soaddr列,如果是,那么你将得到arcust地址。

然而,因为地址数据可能应该保持在一起意味着您应该从1个表中选择和整个地址而不是可能合并,您应该坚持使用您的case语句但是总是测试1字段以确定是否存在soaddr该字段应该是该表的唯一ID(如果不存在,如果不使用另一列,如Address1。

SELECT DISTINCT a.custno, b.company,
    CASE WHEN c.UniqueId IS NULL THEN b.address1
    ELSE c.address1
    END as address,
    CASE WHEN c.UniqueId IS NULL THEN b.city
    ELSE c.city
    END as city,
    CASE WHEN c.UniqueId IS NULL THEN b.addrstate
    ELSE c.addrstate
    END as addrstate,
    CASE WHEN c.UniqueId IS NULL THEN b.zip
    ELSE c.zip
    END as zip,
    invno, descrip, qtyshp, price, extprice, b.tax, invdte 
FROM artran a
LEFT JOIN arcust b ON a.custno = b.custno
LEFT JOIN soaddr c ON a.custno = c.custno