Transact-SQL의 대칭 차분 연산?


10

난 항상에 대해 알고 UNIONSQL 연산자하지만 최근이 다른 세트 사업자 있었다 것을 발견 INTERSECT하고 EXCEPT. 네 번째 큰 집합 연산자 인 대칭 차이 (예 :의 반대 INTERSECT) 를 수행하는 연산자를 찾을 수 없습니다 .

다음과 같은 것을 사용하여 원하는 출력을 얻을 수있는 것처럼 보입니다.

SELECT Field FROM A UNION SELECT Field FROM B 
EXCEPT
SELECT Field FROM A INTERSECT SELECT Field FROM B

(우선 순위가 있다고 가정) 또는 완전 조인 방지를 수행하여 :

SELECT A.Field, B.Field
FROM A
FULL JOIN B ON B.Id = A.Id
WHERE B.Id IS NULL OR A.Id IS NULL

그러나이 두 가지 모두 특히 다른 세 가지 기본 집합 작업에 비해 집중적 인 쿼리처럼 보입니다. SQL에 대칭적인 차이 연산이 있고 설명서에서 찾을 수 없습니까? 아니면 T-SQL로 구현할 수있는 "정식적인"방법이 있습니까?


2
(a EXCEPT b) UNION ALL (b EXCEPT a);더 효율적일 수 있습니다.
ypercubeᵀᴹ

3 개의 조인 또는 조인 유사 작업을 수행하는 @ypercube 이것이 전체 조인보다 더 효율적인 이유는 생각할 수 없습니다.
usr

@usr 실제로는 3이 아닌 2 개의 조인과 유사한 작업입니다. Union All은 훨씬 적은 비용이 드는 작업입니다. FULL JOIN더 효율적일 수 있다는 데 동의합니다 . 테스트하면 어느 것이 가장 좋은지 알 수 있습니다. 물론 각 테이블에서 더 많은 / 다른 열이 필요한 경우 솔루션을 쉽게 확장 할 수 없습니다.
ypercubeᵀᴹ

답변:


3

모든 세트 연산자는 결합 또는 결합 유사 연산자로 변환됩니다. 쿼리 계획에서이를 확인할 수 있습니다.

이러한 이유 때문에 귀하가 가진 완전 외부 조인이 가장 효율적입니다. 물론, 옵티마이 저가 잘못된 계획을 선택하고 재 작성이 운 좋게 더 잘 수행되는 드문 상황은 무시하십시오. 이것은 항상 일어날 수 있습니다.


그러나 집합 연산자를 사용하는 이유는 "추가 열"을 만들지 않기 때문입니다 ... 같은 일을 SELECT Id FROM A WHERE <stuff> EXCEPT Select Id FROM A WHERE <other stuff>하고 단일 목록을 얻을 수 있습니다 Id. 전체 조인으로 어떻게하는지 알 수 없습니다 ... 두 개의 Id열 집합을 처리 하고 다시 함께 결합해야합니까?
KutuluMike

말할 수 있습니다 ISNULL(a.Col, b.Col) AS Col. 이를 파생 테이블 또는 CTE로 랩핑하고 추가 조작을 위해 "접힌"결과 세트를 사용할 수 있습니다. (Btw, 대칭 차이 연산자가 있어야한다는 데 동의합니다.)
usr

2
@MichaelEdenfield 반면 에, 비교 / 구별에 사용되지 않는 다른 열을 원할 때는 어떻습니까? 교차 / 제외가 아닌 조인으로 할 수 있습니다. 그래서 어떤 경우에는 변형이 실제로 훨씬 더 복잡 해지는 것을 알 수 있습니다.
Aaron Bertrand

2

나는 이것이 꽤 좋은 해결책이라고 생각합니다. Not Exists 하위 쿼리와 함께 두 개의 선택 사이에 통합을 사용합니다. 투영에 일치하지 않는 필드를 포함 할 수 있으므로 Union과 Except를 결합하는 것보다 낫습니다.

SELECT  'A' TableName, FileType FROM KFX_Inventory I 
    WHERE Not Exists (Select Top 1 1 from KFX_FileType FT WHERE FT.FileType = I.FileType)
UNION ALL
SELECT  'B', FileType FROM KFX_FILEType FT 
    WHERE Not Exists (Select Top 1 1 from KFX_Inventory I WHERE FT.FileType = I.FileType)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.