2016-08-26 2 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 작업을하고 있으며 많은 시간을 검사하는 것은 텍스트 값뿐 아니라 ISNULL (, '') IS NULL을 사용하여이 열을 감싸기 때문에 빈 문자열인지 확인해야합니다. https://msdn.microsoft.com/en-us/library/ms184325.aspx –

답변

2

가 잘못된 값을 반환하는 이유는 귀하의 경우 문 그렇지 않으면 THEN &의 모든 부분이 arcust를 가리키는 B 테이블 별칭을 참조하기 때문에 항상 arcust 값을 반환하도록 설정이 때문이다. 그 사이에 @ServerSentinel이 원하는 결과를 얻지 못한다고 잘못 지적하여 null을 잘못 비교합니다. 그것은 기본적으로 당신을위한 케이스 문을 기록하고를 반환하기 때문에 C 테이블 별칭을 가리키고 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를 널을 비교하기 위해 다음과 같이 쿼리를 수정 최초의 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 필드를 테스트하여 필드가 있어야하는 soaddr이 있는지 확인해야합니다 Address1과 같은 다른 열을 사용하지 않는 경우 해당 테이블의 고유 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 =과 (와) 비교할 수 없습니다. 대신 use가 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