2012-10-02 1 views
2

하지 않고 여러 데이터 세트를 결합 :
SQL Server는 세 개의 테이블 따, TB, TC 감안할 때 중복 데이터

Ta(ID, Field1) 
Tb(ID, Field2) 
Tc(ID, Field3) 

주어진 데이터 예 :

Ta 
ID Field1 
--------- 
1 A 
1 B 

Tb 
ID Field2 
--------- 
1 C 
1 D 
2 E 

Tc 
ID Field3 
--------- 
1 F 
2 G 
2 H 

질문 : 어떻게이 가입하실 수 있습니다 돌려주는 데이터 :

ID Field1 Field2 Field3 
----------------------- 
1 A  C  F 
1 B  D  NULL 
2 NULL E  G 
2 NULL NULL H 

외부 조인을 사용하여이 작업을 수행 할 수 있다고 생각했지만 그럴 것 같지 않습니다. 중복 행없이 모든 정보를 다시 가져 오는 한 그룹화 순서는 중요하지 않습니다.

명확히하기. 결과 집합이 최소 행 수의 모든 데이터를 반환하는 한 실제로 어떤 조합을 가져야할지 신경 쓰지 않습니다. 여기에 내가하려고하는 것에 대한보다 현실적인 예가 있습니다 :

사람이 있다면 John에게 전화하십시오. 하지만, 내가 말했듯이

select coalesce(ta.id, tb.id, tc.id), ta.field1, tb.field2, tc.field3 
from (select ta.*, row_number() over (partition by id order by (select NULL)) as seqnum 
     from ta 
    ) ta full outer join 
    (select tb.*, row_number() over (partition by id order by (select NULL)) as seqnum 
     from tb 
    ) tb 
    on ta.id = tb.id and 
     ta.seqnum = tb.seqnum 
    (select tc.*, row_number() over (partition by id order by (select NULL)) as seqnum 
     from tc 
    ) tc 
    on coalesce(ta.id, tb.id) = tc.id and 
     coalesce(ta.seqnum, tb.seqnum) = tc.seqnum 
group by coalesce(ta.id, tb.id, tc.id), 
     coalesce(ta.seqnum, tb.seqnum, tc.seqnum) 
order by 1, 2 

:

PID Email   Tel 
---------------------- 
John [email protected] 011 
John [email protected] 022 
John [email protected] NULL 
+3

입니까? – Lamak

+1

'1 A D F'은 어떻습니까? 그리고'1 B C F'? 왜 그걸 돌려 보내지 않는 거지, 네가 돌아 오는 길에서 분명히 빠져있다. 그렇지 않니? 당신이 반응하기 전에, 멈추고 생각해보십시오, 그리고 아마 당신은 당신의 요구 사항에 대한 실제 문제를 깨닫게 될 것입니다. –

+3

당신의 조합은 원래 테이블에있는 행의 순서에 의존하는 것처럼 보입니다. SQL (및 SQL Server)에서 테이블의 행 순서는 지정되지 않습니다. 주문을 결정할 행 번호 또는 ID 열 또는 날짜가 있습니까? –

답변

3

당신은 다음과 가까이 올 수 있습니다 : I 반환 할

PID Email 
--------- 
John [email protected] 
John [email protected] 
John [email protected] 

PID Tel 
-------- 
John 011 
John 022 

: 그는 두 개의 전화 번호와 세 개의 이메일 주소가 내 의견에 테이블의 행 순서는 보장되지 않으므로 예상 한 순서대로 나오지 않을 수 있습니다. 샘플 데이터로, 당신은 사용할 수 있습니다

over (partition by id order by field<n>) 

을 필드이 (가)

3

여기 CTE의와 조합을 사용하여 대안이다, 순서화 정의하면, MIN으로 널 (null)을 제외 할 수 있습니다. 주문을 보장하는 것은 아니지만 신분증이 모두 존재하는 한 당신은 상관하지 않는다고 말한 것입니다.

SQL 바이올린 here

WITH TaRanked AS 
(
    SELECT ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Field1) as Rnk, ID, Field1 
    FROM Ta 
), 
TbRanked AS 
(
    SELECT ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Field2) as Rnk, ID, Field2 
    FROM Tb 
), 
TcRanked AS 
(
    SELECT ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Field3) as Rnk, ID, Field3 
    FROM Tc 
), 
TUnion AS 
(
    SELECT Rnk, ID, Field1, NULL AS Field2, NULL AS Field3 
     FROM TaRanked 
    UNION ALL 
    SELECT Rnk, ID, NULL, Field2, NULL 
     FROM TbRanked 
    UNION ALL 
    SELECT Rnk, ID, NULL, NULL, Field3 
     FROM TcRanked 
) 
SELECT ID, MIN(Field1), MIN(Field2), MIN(Field3) 
    FROM TUnion 
    GROUP BY ID, Rnk 
    ORDER BY ID, Rnk 

결과는 왜 ID = 3에 할당 된 마지막 행이

1 A  C  F 
1 B  D  (null) 
2 (null) E  G 
2 (null) (null) H 
+0

Gordon Linoff의 대답이 나를 위해 일한 것처럼 나는 이것을 시도 할 기회를 얻지 못했습니다. 즉, 이것은 똑같은 일을하지만 훨씬 더 가독적인 방식으로 나타납니다 (+1). 나는 유권자들이 여기에서 그것을 가져 가게 할 것이다! :) –

+0

Gordon이 맞습니다 - 파티션이 최소 행을 보장하는 데 필요합니다. 이것은 또한 원하는 순서를 설정합니다. 나는 갱신했다. – StuartLC