2017-01-15 2 views
1

으로 여러 테이블을 병합 내가 몇 내가 이런 식으로 가입 한 테이블이 있습니다은/가입 같은 키

SELECT * 
FROM tableA AS A 
     FULL OUTER JOIN tableB AS B 
        ON B.KEY = A.KEY 
     FULL OUTER JOIN tableC AS C 
        ON C.KEY = A.KEY 
     FULL OUTER JOIN tableD AS D 
        ON D.KEY = A.KEY 

이 잘 작동하지만 내가 언젠가 키가 모든 테이블에 존재하지 않는 별도의 행을 얻을 수 있습니다.

WITH tableA([KEY], payloadColumn) AS 
(
SELECT 1, 'var_A1' 
), tableB([KEY], payloadColumn) AS 
(
SELECT 2, 'var_B2' 
), tableC([KEY], payloadColumn) AS 
(
SELECT 1, 'var_C1' 
), tableD([KEY], payloadColumn) AS 
(
SELECT 2, 'var_D2' 
) 
SELECT * FROM tableA as A 
FULL OUTER JOIN tableB as B ON B.[KEY] = A.[KEY] 
FULL OUTER JOIN tableC as C ON C.[KEY] = A.[KEY] 
FULL OUTER JOIN tableD as D ON D.[KEY] = A.[KEY] 

반환

+------+---------------+------+---------------+------+---------------+------+---------------+ 
| KEY | payloadColumn | KEY | payloadColumn | KEY | payloadColumn | KEY | payloadColumn | 
+------+---------------+------+---------------+------+---------------+------+---------------+ 
| 1 | var_A1  | NULL | NULL   | 1 | var_C1  | NULL | NULL   | 
| NULL | NULL   | 2 | var_B2  | NULL | NULL   | NULL | NULL   | 
| NULL | NULL   | NULL | NULL   | NULL | NULL   | 2 | var_D2  | 
+------+---------------+------+---------------+------+---------------+------+---------------+ 

하지만 난 그들 모두가 결과에 동일한 행에있을 필요 (하지 2 두 행). 어떻게해야합니까? 모든 테이블은 단지 조인 병합 함께 체인 수있는이에 대한 [KEY] INCLUDE (payloadColumn) 실행 계획에 포함 인덱스가있는 경우

+0

''FULL JOIN '으로'NULL'을 얻는 것은'JOIN'에서 제약 조건과 일치하는 행이 * 없다는 것을 의미합니다. 그것은'FULL JOIN'의 정의입니다. 대신 일치 항목이없는 행을 필터링하려면 INNER JOIN을 사용하십시오. – jpmc26

+0

빠른 생각 : 모든 네 개의 테이블의 모든 null이 아닌 키를 합한 뷰를 만든 다음 기본 쿼리에서이 뷰를 기본 ('FROM') 테이블로 사용하고 페이로드를 왼쪽 조인 – dlatikay

+0

@ jpmc26 - 그건 그들이 요구하는 것이 아닙니다. –

답변

3

:

CREATE VIEW ABCD 

AS 

SELECT [KEY] FROM tableA 
UNION 
SELECT [KEY] FROM tableB 
UNION 
SELECT [KEY] FROM tableC 
UNION 
SELECT [KEY] FROM tableD 

옵션이 될 수 없습니다 뷰를 생성하는 단계; 이 경우 CTE로 다시 작성하십시오. 적어도 이런 식으로 실행 계획은 인덱스를 계속 사용합니다 ([KEY]은 PK 또는 인덱싱 된 것으로 가정).

SELECT 
    K.[KEY] as sameKey, 
    A.payloadColumn, 
    B.payloadColumn, 
    C.payloadColumn, 
    D.payloadColumn 
FROM ABCD K 
LEFT JOIN tableA A ON A.[KEY]=K.[KEY] 
LEFT JOIN tableB B ON B.[KEY]=K.[KEY] 
LEFT JOIN tableC C ON C.[KEY]=K.[KEY] 
LEFT JOIN tableD D ON D.[KEY]=K.[KEY] 

귀하의 아이디어가 잘못 되었다면, 자세히 설명해주십시오.

+0

나는 질문을 명확히하기 위해 편집했고, 비 핵심 열 (최소한의 예에서는 불필요 함)은 길을 잃어 버렸다. 이제 다시 추가되었습니다. 따라서 귀하의 답변은 그 내용과 일치해야합니다. –

+0

나는 매우 감사한다. 그것은 내가 필요한 것입니다. 많은 감사 – user625079

3

당신은 COALESCE

WITH tableA([KEY], payloadColumn) 
    AS (SELECT 1, 
       'var_A1'), 
    tableB([KEY], payloadColumn) 
    AS (SELECT 2, 
       'var_B2'), 
    tableC([KEY], payloadColumn) 
    AS (SELECT 1, 
       'var_C1'), 
    tableD([KEY], payloadColumn) 
    AS (SELECT 2, 
       'var_D2') 
SELECT COALESCE(A.[KEY], B.[KEY], C.[KEY], D.[KEY]) AS [KEY], 
     A.payloadColumn, 
     B.payloadColumn, 
     C.payloadColumn, 
     D.payloadColumn 
FROM tableA AS A 
     FULL OUTER JOIN tableB AS B 
        ON B.[KEY] = A.[KEY] 
     FULL OUTER JOIN tableC AS C 
        ON C.[KEY] = COALESCE(A.[KEY], B.[KEY]) 
     FULL OUTER JOIN tableD AS D 
        ON D.[KEY] = COALESCE(A.[KEY], B.[KEY], C.[KEY]); 

반환

+-----+---------------+---------------+---------------+---------------+ 
| KEY | payloadColumn | payloadColumn | payloadColumn | payloadColumn | 
+-----+---------------+---------------+---------------+---------------+ 
| 1 | var_A1  | NULL   | var_C1  | NULL   | 
| 2 | NULL   | var_B2  | NULL   | var_D2  | 
+-----+---------------+---------------+---------------+---------------+ 

를 사용할 수 있습니다. 영업 이익, 그들의 마지막 편집의 이전 버전에서 초안에 내 제안 된 솔루션을 기반으로

enter image description here

+0

당신의 노력을위한 탱크. 나는 dlatikay에서 위트를 달렸다. – user625079