복붙노트

[SQL] 어떻게 재 작성하는 구별된다과 구별되지 않는 이유는 무엇입니까?

SQL

어떻게 재 작성하는 구별된다과 구별되지 않는 이유는 무엇입니까?

어떻게 표준이 구별된다 그들을 지원하지 않는 마이크로 소프트 SQL 서버 2008R2로 SQL 구현에 사업자 구별을지지 않습니다 포함 된 표현을 다시 쓸 수 있습니까?

해결법

  1. ==============================

    1.2003 : (가) 기능 SQL의 T151으로 소개 된 술어 구별된다 : SQL의 기능 T152으로 추가되었다 1999, 그것의 읽을 부정, DISTINCT을지지 않습니다. 이러한 조건의 목적은 두 값을 비교 한 결과이 중 알 수없는, 참 또는 거짓 결코 것을 보장하는 것입니다.

    2003 : (가) 기능 SQL의 T151으로 소개 된 술어 구별된다 : SQL의 기능 T152으로 추가되었다 1999, 그것의 읽을 부정, DISTINCT을지지 않습니다. 이러한 조건의 목적은 두 값을 비교 한 결과이 중 알 수없는, 참 또는 거짓 결코 것을 보장하는 것입니다.

    이 술어는 오히려 정확하게 그들을 모방하는 복잡하고 (행, 배열 및 멀티 세트 포함) 비슷한 유형으로 작동합니다. 우리가 널 (null) 인수 / 피연산자를 확인하여 꽤 멀리 얻을 수 있도록 그러나 SQL Server는 이러한 유형의 대부분을 지원하지 않습니다

    그것은 알 수없는 해당 FALSE 또는 NULL 평가합니다 고려하는 것이 실패로 자신의 대답이 올바르지 않습니다. 예를 들어, NULL은 False로 평가해야 NULL 구별된다. 마찬가지로, 1 False로 평가해야 NULL 구별을지지 않습니다. 두 경우 모두, 당신의 표정은 알을 얻을 수 있습니다.

  2. ==============================

    2.레버리지와 같은 또 다른 솔루션 I INTERSECT와 함께 EXISTS의 진정한 두 값 부울 결과입니다. 이 솔루션은 SQL 서버 2005 +에서 작동합니다.

    레버리지와 같은 또 다른 솔루션 I INTERSECT와 함께 EXISTS의 진정한 두 값 부울 결과입니다. 이 솔루션은 SQL 서버 2005 +에서 작동합니다.

    설명 된 바와 같이, INTERSECT 취급 동등한 같은 두 NULL 값 모두에 해당하므로 수율이 존재하고, 하나의 행 INTERSECT 결과 NULL이다 그렇다면.

    당신은 당신이 두 개의 테이블에서 비교해야 여러 널 (NULL) 열이있는 경우이 방법은 훨씬 더 간결하다. 예를 들어,보다 TableA의 COL1, Col2의 또는 열 3 값이 다를 TableB의 행을 반환 다음을 사용할 수있다 :

    SELECT *
    FROM TableA A
       INNER JOIN TableB B ON A.PK = B.PK
    WHERE NOT EXISTS(
       SELECT A.Col1, A.Col2, A.Col3
       INTERSECT
       SELECT B.Col1, B.Col2, B.Col3);
    

    폴 화이트 자세히이 해결 방법을 설명합니다 : http://web.archive.org/web/20180422151947/http://sqlblog.com:80/blogs/paul_white/archive/2011/06/22/undocumented-query-plans-equality-comparisons.aspx

  3. ==============================

    3.SQL 표준을 구현하지 않는 SQL 구현이 구별된다 및 운영자 구별하지 않는 경우, 당신은 때 다음 등식을 사용하여 포함 된 식을 다시 작성할 수 있습니다 :

    SQL 표준을 구현하지 않는 SQL 구현이 구별된다 및 운영자 구별하지 않는 경우, 당신은 때 다음 등식을 사용하여 포함 된 식을 다시 작성할 수 있습니다 :

    일반적으로 :

    a IS DISTINCT FROM b <==>
    (
        ((a) IS NULL AND (b) IS NOT NULL)
    OR
        ((a) IS NOT NULL AND (b) IS NULL)
    OR
        ((a) <> (b))
    )
    
    a IS NOT DISTINCT FROM b <==>
    (
        ((a) IS NULL AND (b) IS NULL)
    OR
        ((a) = (b))
    )
    

    이 답변은 문맥에서 사용하면 잘못된입니다 UNKNOWN와 FALSE 문제의 차이. 그게 비록 드문 일이라고 생각합니다. @ChrisBandy에 의해 허용 대답을 참조하십시오.

    자리 표시 자 값이 실제로 데이터 발생하지 않는 식별 할 수있는 경우에, COALESCE는 대안입니다 :

    a IS DISTINCT FROM b <==> COALESCE(a, placeholder) <> COALESCE(b, placeholder)
    a IS NOT DISTINCT FROM b <==> COALESCE(a, placeholder) = COALESCE(b, placeholder)
    
  4. ==============================

    4.재 작성에 하나주의해야 할 점은 구별된다 및 SQL Server를 사용하는 경우, 적어도 사용하여 인덱스를 방해하지 않는 것이 구별을지지 않습니다. 즉, 다음을 사용하는 경우 :

    재 작성에 하나주의해야 할 점은 구별된다 및 SQL Server를 사용하는 경우, 적어도 사용하여 인덱스를 방해하지 않는 것이 구별을지지 않습니다. 즉, 다음을 사용하는 경우 :

    WHERE COALESCE(@input, x) = COALESCE(column, x)
    

    SQL Server는 열이 포함되어있는 인덱스를 사용할 수 없습니다. 따라서 WHERE 절에,이 양식을 사용하는 것이 바람직 할 것

    WHERE @input = column OR (@input IS NULL AND column IS NULL)
    

    컬럼에 대한 인덱스를 활용합니다. (괄호은 명확성을 위해 사용됨)

  5. ==============================

    5.그냥 존 켈러의 답변을 확장합니다. 내가 사용하는 것을 선호 존재하고 패턴 제외 :

    그냥 존 켈러의 답변을 확장합니다. 내가 사용하는 것을 선호 존재하고 패턴 제외 :

    a IS DISTINCT FROM b
    <=>
    EXISTS (SELECT a EXCEPT SELECT b)
    -- NOT EXISTS (SELECT a INTERSECT SELECT b)
    

    a IS NOT DISTINCT FROM  b
    <=>
    NOT EXISTS (SELECT a EXCEPT SELECT b)
    -- EXISTS (SELECT a INTERSECT SELECT b)
    

    하나의 특정 이유. INTERSECT로 반전되는 반면 정렬 NOT.

    SELECT 1 AS PK, 21 AS c, NULL  AS  b
    INTO tab1;
    
    SELECT 1 AS PK, 21 AS c, 2 AS b
    INTO tab2;
    
    SELECT *
    FROM tab1 A
    JOIN tab2 B ON A.PK = B.PK
    WHERE EXISTS(SELECT A.c, A.B
                  EXCEPT
                  SELECT B.c, B.b);
    

    DB 휘티 d 혀라도

  6. ==============================

    6.참고로, FROM DISTINCT [NOT] IS 가장 표준 (및 판독) 구현은 잘 포맷 CASE 발현 될 것이다. 들면는 구별된다 :

    참고로, FROM DISTINCT [NOT] IS 가장 표준 (및 판독) 구현은 잘 포맷 CASE 발현 될 것이다. 들면는 구별된다 :

    CASE WHEN [a] IS     NULL AND [b] IS     NULL THEN FALSE
         WHEN [a] IS     NULL AND [b] IS NOT NULL THEN TRUE
         WHEN [a] IS NOT NULL AND [b] IS     NULL THEN TRUE
         WHEN [a] =               [b]             THEN FALSE
         ELSE                                          TRUE
    END
    

    분명히, (특히 존 켈러의, INTERSECT를 사용하여)보다 간결 다른 솔루션입니다.

    더 자세한 사항은 여기에

  7. ==============================

    7.(가) 논리 구별된다 그들은 약에 발생합니다 하나의 조건식에 SQL 서버에서 컴파일되고 결국 때문에 이전 예제보다 더 잘 수행에 대한 이러한 표현은 좋은 대용품이 될 수 있습니다. 필터 식에 절반 오퍼레이터 비용. 그러나 그들은 그들이 기본 비교를 수행하기 위해 중첩 된 ISNULL과 NULLIF 함수를 사용하여, 본질적으로 크리스 밴디에 의해 제공되는 솔루션과 동일합니다.

    (가) 논리 구별된다 그들은 약에 발생합니다 하나의 조건식에 SQL 서버에서 컴파일되고 결국 때문에 이전 예제보다 더 잘 수행에 대한 이러한 표현은 좋은 대용품이 될 수 있습니다. 필터 식에 절반 오퍼레이터 비용. 그러나 그들은 그들이 기본 비교를 수행하기 위해 중첩 된 ISNULL과 NULLIF 함수를 사용하여, 본질적으로 크리스 밴디에 의해 제공되는 솔루션과 동일합니다.

    (당신이 원하는 경우 ... 분명히 ISNULL은 유착으로 치환 될 수있다)

  8. ==============================

    8.

    a IS NOT DISTINCT FROM b
    

    로 다시 작성할 수 있습니다 :

    (a IS NOT NULL AND b IS NOT NULL AND a=b) OR (a IS NULL AND b is NULL)
    
    a IS DISTINCT FROM b
    

    로 다시 작성할 수 있습니다 :

    NOT (a IS NOT DISTINCT FROM b)
    
  9. ==============================

    9.이것은 오래된 질문과 새 응답이있다. 이해 및 유지 보수가 용이하다.

    이것은 오래된 질문과 새 응답이있다. 이해 및 유지 보수가 용이하다.

    -- a IS DISTINCT FROM b
    CASE WHEN (a = b) OR (a IS NULL AND b IS NULL) THEN 1 ELSE 0 END = 0
    
    -- a IS NOT DISTINCT FROM b
    CASE WHEN (a = b) OR (a IS NULL AND b IS NULL) THEN 1 ELSE 0 END = 1
    

    IS는이 구문 대안 [NOT] 주요 SQL 데이터베이스에서 작동 DISTINCT FROM (끝에 링크 참조) 것을 주목해야한다. 이것과 대안은 정교 여기에 설명되어 있습니다

  10. from https://stackoverflow.com/questions/10416789/how-to-rewrite-is-distinct-from-and-is-not-distinct-from by cc-by-sa and MIT license