programing

SQL Server 20008R2에서 ISDRICT FROM과 ISDRICT FROM을 다시 작성하는 방법은 무엇입니까?

javajsp 2023. 7. 18. 21:32

SQL Server 20008R2에서 ISDRICT FROM과 ISDRICT FROM을 다시 작성하는 방법은 무엇입니까?

표준을 포함하는 식을 다시 작성하는 방법IS DISTINCT FROM그리고.IS NOT DISTINCT FROMMicrosoft SQL Server 2008 R2의 SQL 구현에서 운영자를 지원하지 않는 운영자?

IS DISTINCT FROM는 SQL 수 있는 "SQL:1999"와 "T151",IS NOT DISTINCT FROMSQL:2003의 기능 T152로 추가되었습니다.이러한 술어의 목적은 두 값을 비교한 결과가 True 또는 False이며 알 수 없음이 아님을 보장하는 것입니다.

이러한 술어는 모든 유사한 유형(행, 배열 및 다중 집합 포함)에서 작동하므로 정확하게 에뮬레이트하기가 다소 복잡합니다.그러나 SQL Server는 이러한 유형의 대부분을 지원하지 않으므로 null 인수/연산자를 확인하면 다음과 같은 이점을 얻을 수 있습니다.

  • a IS DISTINCT FROM b다음과 같이 다시 작성할 수 있습니다.

    ((a <> b OR a IS NULL OR b IS NULL) AND NOT (a IS NULL AND b IS NULL))
    
  • a IS NOT DISTINCT FROM b다음과 같이 다시 작성할 수 있습니다.

    (NOT (a <> b OR a IS NULL OR b IS NULL) OR (a IS NULL AND b IS NULL))
    

당신의 대답은 그것을 고려하지 않기 때문에 부정확합니다.FALSE OR NULL알 수 없음으로 평가됩니다.예를들면,NULL IS DISTINCT FROM NULLFalse로 평가해야 합니다.유사하게,1 IS NOT DISTINCT FROM NULLFalse로 평가해야 합니다.두 경우 모두 식을 사용하면 알 수 없습니다.

제가 좋아하는 또 다른 솔루션은 EXISTS와 결합된 진정한 두 값 부울 결과를 활용합니다.이 솔루션은 SQL Server 2005+에서 작동해야 합니다.

  • a IS NOT DISTINCT FROM b다음과 같이 쓸 수 있습니다.

    EXISTS(SELECT a INTERSECT SELECT b)

문서화된 것처럼, ENTRESS는 두 NULL 값을 동일하게 취급하므로, 둘 다 NULL이면 ENTRESS는 단일 행으로 결과적으로 true를 산출합니다.

  • a IS DISTINCT FROM b다음과 같이 쓸 수 있습니다.

    NOT EXISTS(SELECT a INTERSECT SELECT b)

이 방법은 두 개의 표에서 비교해야 하는 귀무 가설 열이 여러 개 있는 경우 훨씬 더 간결합니다.예를 들어, 표 B에서 표 A와 Col1, Col2 또는 Col3에 대한 값이 다른 행을 반환하려면 다음을 사용할 수 있습니다.

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);

Paul White는 이 해결 방법에 대해 자세히 설명합니다. https://sql.kiwi/2011/06/documented-query-plans-equality-comparations.html

표준 SQL을 IS DISTINCT FROM그리고.IS NOT DISTINCT FROM연산자의 경우 다음 동등성을 사용하여 연산자를 포함하는 식을 다시 작성할 수 있습니다.

일반적으로:

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)

켈러의 답변을 연장하기 위해서입니다.사용하는 것을 선호합니다.EXISTS그리고.EXCEPT패턴:

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)

한 가지 특별한 이유로 NOT 정렬되어 있는 에 와일하 반에면 는치에 반▁is ▁whereas면▁aligned.INTERSECT반전되었습니다.


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 Fidle 데모

재작성 시 한 가지 주의할 점은 적어도 SQL Server를 사용할 때는 인덱스 사용을 방해하지 않는다는 것입니다.즉, 다음을 사용하는 경우:

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

SQL Server는 열을 포함하는 인덱스를 사용할 수 없습니다.따라서 WHERE 절에서는 다음과 같은 형식을 사용하는 것이 좋습니다.

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

열에 대한 인덱스를 사용합니다. (명확한 설명을 위해 부모만 사용됨)

SQL Server 2022 CTP 2.1(및 클라우드 버전)부터 IS[NOT] DISTINCT FROM이 지원됨을 알려드리게 되어 기쁘게 생각합니다.따라서 일반적으로 해결책이 더 이상 필요하지 않기를 바라지만 여전히 효과가 있습니다.설명서 페이지 링크

이러한 표현식은 IS DISTINCT FROM 논리를 대체하는 데 유용할 수 있으며 SQL 서버에서 단일 술어 표현식으로 컴파일되어 필터 표현식에 대한 연산자 비용의 약 절반을 초래하므로 이전 예제보다 성능이 우수합니다.이들은 기본적으로 Chris Bandy가 제공한 솔루션과 동일하지만 중첩된 ISNULL 및 NULLIF 함수를 사용하여 기본 비교를 수행합니다.

(... 분명히 ISNULL은 COALESCE로 대체될 수 있습니다.)

  • a IS DISTINCT FROM b다음과 같이 다시 작성할 수 있습니다.

    ISNULL(NULLIF(a, b), NULLIF(b, a)) IS NOT NULL

  • a IS NOT DISTINCT FROM b다음과 같이 다시 작성할 수 있습니다.

    ISNULL(NULLIF(a, b), NULLIF(b, a)) IS NULL

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)

이것은 오래된 질문이고 새로운 답이 있습니다.그것은 이해하고 유지하는 것이 더 쉽습니다.

-- 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] DISTINCT FROM는 모든 주요 SQL 데이터베이스에서 작동합니다(마지막 링크 참조).이것과 대안은 여기에 자세히 설명되어 있습니다.

다을사용여맞지정춤법하를 사용하여 CASE

참고로, 가장 표준적인(그리고 읽을 수 있는) 구현은IS [ NOT ] DISTINCT FROM 다듬어진 ▁a▁be▁would다것니입▁well-formatted.CASE표현.위해서IS DISTINCT FROM:

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

분명히, 다른 해결책들(특히, John Keller의 해결책들, 사용합니다.INTERSECT가 더 가 더 간결합니다.

자세한 내용은 여기에 있습니다.

용사를 합니다.DECODE

Server에 인 것은 완성도를은 "SQL Server"와 "DB2"와 "을 참조하십시오.DECODE()함수. 다음을 에뮬레이트할 수 있는 경우:

-- a IS DISTINCT FROM b
DECODE(a, b, 1, 0) = 0

-- a IS NOT DISTINCT FROM b
DECODE(a, b, 1, 0) = 1

언급URL : https://stackoverflow.com/questions/10416789/how-to-rewrite-is-distinct-from-and-is-not-distinct-from-in-sql-server-20008r2