by 정명호 [SQL Query] join 중복 [2018.05.28 11:47:05]
create table #a ( emp varchar(10))
create table #b ( emp varchar(10), txt1 varchar(10) )
create table #c ( emp varchar(10), txt2 varchar(10))
insert into #a values ('001');
insert into #a values ('002');
insert into #a values ('003');
insert into #b values ('001','가');
insert into #b values ('001','나');
insert into #b values ('003','라');
insert into #c values ('001','A');
insert into #c values ('002','A');
insert into #c values ('003','A');
insert into #c values ('003','B');
insert into #c values ('003','C');
SELECT A.EMP, B.txt1, C.txt2
FROM #A AS A
FULL OUTER JOIN #b AS B
ON A.EMP = B.EMP
FULL OUTER JOIN #c AS C
ON A.EMP = C.EMP
실행하면 원하는 결과
001 가 A 001 가 A
001 나 A 001 나 NULL
002 NULL A ====>>> 002 NULL A
003 라 A 003 라 A
003 라 B 003 NULL B
003 라 C 003 NULL C
즉, 테이블별로 있는 건수대로 순차적으로 나오게 하고 싶습니다.
그런데 inner join 이던 full outer join 어느걸로 해도 원하는결과는 안나오내요.
문제는 테이브링 3개가아니고 7개가 더 많습니다.
좋은 쿼리 방법이 없을까요? row_number, distincty 등 해봤는데 잘 안되내요.
좋은 방법이 없을까요?
-- FULL OUTER JOIN SELECT C.EMP , CASE WHEN ROW_NUMBER() OVER(PARTITION BY C.EMP , B.TXT1 ORDER BY TXT1 ) = 1 THEN B.TXT1 ELSE '' END AS TXT1 , CASE WHEN ROW_NUMBER() OVER(PARTITION BY C.EMP , C.TXT2 ORDER BY TXT1 ) = 1 THEN C.TXT2 ELSE '' END AS TXT2 FROM B FULL OUTER JOIN C ON B.EMP = C.EMP ORDER BY EMP , TXT1 , TXT2 -- LEFT OUTER JOIN SELECT A.EMP , CASE WHEN ROW_NUMBER() OVER(PARTITION BY A.EMP , B.TXT1 ORDER BY TXT1 ) = 1 THEN B.TXT1 ELSE '' END AS TXT1 , CASE WHEN ROW_NUMBER() OVER(PARTITION BY A.EMP , C.TXT2 ORDER BY TXT1 ) = 1 THEN C.TXT2 ELSE '' END AS TXT2 FROM A LEFT OUTER JOIN B ON A.EMP = B.EMP LEFT OUTER JOIN C ON A.EMP = C.EMP ORDER BY EMP , TXT1 , TXT2
-- 이렇게 억지로 만들 수는 있지만 절대 추천하고 싶지는 않습니다. SELECT a.emp , b.rn , b.txt1 , b.txt2 , b.txt3 FROM #a a LEFT OUTER JOIN (SELECT emp , rn , MIN(txt1) txt1 , MIN(txt2) txt2 , MIN(txt3) txt3 FROM (SELECT emp , ROW_NUMBER() OVER(PARTITION BY emp ORDER BY txt1) rn , txt1 , null txt2 , null txt3 FROM #b UNION ALL SELECT emp , ROW_NUMBER() OVER(PARTITION BY emp ORDER BY txt2) rn , null txt1 , txt2 , null txt3 FROM #c UNION ALL SELECT emp , ROW_NUMBER() OVER(PARTITION BY emp ORDER BY txt3) rn , null txt1 , null txt2 , txt3 FROM #d ) b GROUP BY emp, rn ) b ON a.emp = b.emp ORDER BY a.emp, b.rn ;