2016-08-26 35 views
0

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

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 
+1

难道你不想要别人c.address1当soaddr不为空?或者你可以使用'coalesce(c.address1,b.address1)'当使用soaddr时使用arcust.address1。 – xQbert

+0

我做了很多ETL工作,很多次我检查不仅是一个文本值null我需要检查它是否是一个空字符串,所以我用ISNULL包装这些列(,'')IS NULL。请参阅https://msdn.microsoft.com/en-us/library/ms184325.aspx –

回答

2

它返回错误值的原因是,你的case语句是设置总是返回arcust值,因为当时的& ELSE所有部件引用指向arcust的B表的别名。在那之间,并正确地比较null,因为@ServerSentinel恰当地指出你没有得到你想要的结果。修改您的查询,如下所示指向到c表的别名和比较空的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语句为您和返回第一个非空值。所以,你可以简单地写:

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 

,这将给你的soaddr列,如果它不为空,如果是,那么你将得到arcust地址。

但是,因为地址数据应该保持在一起,这意味着您应该从1个表中选择整个地址,而不是可能合并您应该坚持您的case语句,但总是测试1字段以确定是否有soaddr该字段应该是如果不存在另一列(如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 
+0

这就是它!谢谢您的帮助!! – user3394606

3

您无法使用=与NULL比较值。 改为使用null。

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

减去**周围是..:P ...它在两次评估中都返回b.address1 ...对我来说似乎很奇怪我想其他的应该是c.address1。 – xQbert

+0

也可以考虑使用isnull(c.address1,b.address1)或coalesce(c.address1,b.address1)。 coalesce还可以根据需要查看任意数量的字段或查看默认值。合并(c.address1,b.address1,'No Address')。 – serverSentinel