join 할때 여러 테이블에서 있는건수대로 조인되어 나오게 하고 싶습니다. 0 6 1,507

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 등 해봤는데 잘 안되내요. 

좋은 방법이 없을까요?

 

 

by 우리집아찌 [2018.05.28 12:26:46]
-- 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
  

 

 


by 정명호 [2018.05.28 15:43:58]

올~!!! 천재 시내요... 

저 row_number 다시 공부해야겠습니다. 

Partition 에 대해 제가 완벽하게 이해 못한거 같어요

감사합니다. 


by 마농 [2018.05.28 15:48:11]

(b 가 여러건이면 c 는 1건 또는 c 가 여러건이면 b 는 1건)
이렇게 1:다 형태의 자료만 예시로 되어 있어서 우연히 결과가 맞게 나오는 듯 하네요.
양쪽 다 여러건이 되면(다:다) 결과가 이상해 집니다.


by 정명호 [2018.05.28 17:01:33]

그러내요. 음.. 열심히 짜서 돌렸는데...음..

조금 이상하게 나오내요.^^.. 

어째든 답변에 정말 감사드립니다.   다시 한번 볼께요..^^..

 


by 마농 [2018.05.28 13:10:56]

조인키가 별도로 없는 다대다 조인의 경우는 조인 자체를 삼가해야 합니다.
1대다 조인의 경우는 한번까지는 가능하지만
1:다:다 형태로 조인해서는 안됩니다.
테이블이 여러개인 경우에는 더더욱 이렇게 해서는 안되구요.
왜 이렇게 해야 하는지 모르겟지만.. 이렇게 하지 않는것을 추천합니다.
각각 개별 쿼리하여 한 화면에서 함께 뿌려주는 방식으로 해야 하지 않을까? 생각되네요.
억지로 만들수는 있지만 절대 추천하지 않습니다.
DB 종류는 뭔가요? Row_number 을 사용해야 하는데 사용 가능한 DB 인지?


by 마농 [2018.05.28 13:24:40]
-- 이렇게 억지로 만들 수는 있지만 절대 추천하고 싶지는 않습니다.
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
;

 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입