2016-08-26 9 views
0

次のクエリを書きましたが、CASE文が正しくない値を返しています。 soaddrがsoaddrから値を返す代わりに値を持つとき、それはarcustから間違った値を返します。しかし、else文を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

soaddrがnullでない場合は、c.address1を使用しないでください。 arcust.address1を使用している場合は、soaddrを使用して 'coalesce(c.address1、b.address1)'を使用することもできます。 – xQbert

+0

私はたくさんのETL作業をしています。私はテキスト値のNULLだけでなく、空文字列かどうかを調べる必要があるだけでなく、ISNULL(、 '')IS NULLを使用してこれらの列をラップします。 https://msdn.microsoft.com/en-us/library/ms184325.aspx –

答えて

2

それは間違った値を返している理由は、あなたのケースの文はELSE THEN &のすべての部分がarcustを指すBテーブルの別名を参照するため、常にarcust値を返すように設定されていることです。その間に@ServerSentinelがあなたの望む結果を得ていないと誤って間違って比較します。それは基本的にあなたのためのcase文を書き込み、返すので、Cテーブルの別名を指すとNULL ISとしてあなたに大きな助けがここにある)(

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をヌルを比較するために、次のようにクエリを変更します最初の非NULL値。だから、単純に書くことができます:それはnullでなく、それがあるならば、あなたはarcustアドレスを取得する場合、あなたにsoaddr列を与える

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 

を。

しかし、アドレスデータはまとめておく必要があります。つまり、マージする代わりに1つのテーブルからアドレスを選択して全体を選択する必要があります。ケースステートメントに固執する必要がありますが、常に1フィールドをテストして、 Address1などの別の列を使用しない場合、そのテーブルの一意のIDが存在する場合はそのID。

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を返しています...私には奇妙に見えます私はelseがc.address1であるべきだと思います。 – xQbert

+0

また、isnull(c.address1、b.address1)またはcoalesce(c.address1、b.address1)を使用することを検討してください。合体には、必要な数のフィールドを見たり、デフォルト値を戻したりするという追加の利点があります。 coalesce(c.address1、b.address1、 'No Address')。 – serverSentinel

関連する問題