[SQL] 어떻게 재 작성하는 구별된다과 구별되지 않는 이유는 무엇입니까?
SQL어떻게 재 작성하는 구별된다과 구별되지 않는 이유는 무엇입니까?
어떻게 표준이 구별된다 그들을 지원하지 않는 마이크로 소프트 SQL 서버 2008R2로 SQL 구현에 사업자 구별을지지 않습니다 포함 된 표현을 다시 쓸 수 있습니까?
해결법
-
==============================
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.레버리지와 같은 또 다른 솔루션 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.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.재 작성에 하나주의해야 할 점은 구별된다 및 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.그냥 존 켈러의 답변을 확장합니다. 내가 사용하는 것을 선호 존재하고 패턴 제외 :
그냥 존 켈러의 답변을 확장합니다. 내가 사용하는 것을 선호 존재하고 패턴 제외 :
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.참고로, 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.(가) 논리 구별된다 그들은 약에 발생합니다 하나의 조건식에 SQL 서버에서 컴파일되고 결국 때문에 이전 예제보다 더 잘 수행에 대한 이러한 표현은 좋은 대용품이 될 수 있습니다. 필터 식에 절반 오퍼레이터 비용. 그러나 그들은 그들이 기본 비교를 수행하기 위해 중첩 된 ISNULL과 NULLIF 함수를 사용하여, 본질적으로 크리스 밴디에 의해 제공되는 솔루션과 동일합니다.
(가) 논리 구별된다 그들은 약에 발생합니다 하나의 조건식에 SQL 서버에서 컴파일되고 결국 때문에 이전 예제보다 더 잘 수행에 대한 이러한 표현은 좋은 대용품이 될 수 있습니다. 필터 식에 절반 오퍼레이터 비용. 그러나 그들은 그들이 기본 비교를 수행하기 위해 중첩 된 ISNULL과 NULLIF 함수를 사용하여, 본질적으로 크리스 밴디에 의해 제공되는 솔루션과 동일합니다.
(당신이 원하는 경우 ... 분명히 ISNULL은 유착으로 치환 될 수있다)
-
==============================
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.이것은 오래된 질문과 새 응답이있다. 이해 및 유지 보수가 용이하다.
이것은 오래된 질문과 새 응답이있다. 이해 및 유지 보수가 용이하다.
-- 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 (끝에 링크 참조) 것을 주목해야한다. 이것과 대안은 정교 여기에 설명되어 있습니다
from https://stackoverflow.com/questions/10416789/how-to-rewrite-is-distinct-from-and-is-not-distinct-from by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] INSERT에 대한 SQL 주입 (0) | 2020.04.07 |
---|---|
[SQL] 어떻게 별도로 localdb 설치 하는가? (0) | 2020.04.07 |
[SQL] 가장 빠른 방법은 120 만 개 기록을 업데이트 (0) | 2020.04.07 |
[SQL] SQL은 - 소수점 이하 2 자리에서 반올림 (0) | 2020.04.07 |
[SQL] CTE에서 테이블의 업데이트 기록 (0) | 2020.04.07 |