2016-08-26 2 views
0

Я написал следующий запрос, но операторы CASE возвращают неверные значения. Когда soaddr имеет значение вместо того, чтобы возвращать значение из soaddr, оно вернет неправильное значение из дуги. Но если я изменил статус 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

не хотите ли еще 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

Причина, возвращается неверное значение в том, что ваше дело заявление установка всегда возвращает значение arcust, потому что все части THEN ELSE & ссылаться на псевдоним б таблицу, которая указывает на arcust. Между этим и неправильным сопоставлением нулевого значения, как @ServerSentinel, указывает, что вы не получаете желаемых результатов. Измените следующий запрос, чтобы указать псевдоним с таблицы и сравнить нуль, как 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() огромная помощь для вас здесь, потому что она в основном пишет дела о вас и возвращает первое ненулевое значение. Таким образом, вы могли бы просто написать:

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 имеет дополнительное преимущество в том, что вы смотрите на столько полей, сколько хотите, или сохраняете значение по умолчанию. coalece (c.address1, b.address1, «No Address»). – serverSentinel

Смежные вопросы