SQL

LEFT JOIN 중복제거 DISTINCT와 GROUP BY

palette 2021. 6. 3. 22:41

LEFT JOIN은 아마도 SQL 쿼리문을 짜면서 가장 많이 쓰이는 문법 중 하나가 아닐까 싶다.


JOIN에는 여러 종류가 있다. 크게 나누자면 1.LEFT 2.INNER 3.RIGHT인데 사실 RIGHT JOIN은 거의 사용하지 않고 대부분 LEFT JOIN 혹은 INNER JOIN을 주로 사용한다.

참고로 LEFT JOIN과 LEFT OUTER JOIN은 동일하다.

출처: stackoverflow

LEFT JOIN을 여러번 사용하고 싶은 경우의 쿼리는 아래와 같다.


문제는 LEFT JOIN을 하다보면 중복값이 생기면서 데이터가 늘어나는 경우가 있다. LEFT JOIN은 1:1 혹은 N:1의 관계를 가진 테이블 두 개를 조인해야만 전체 ROW 수가 틀어지지 않는다. 만약 1:N의 관게에서 LEFT JOIN을 쓰면 데이터에 변동이 있을 수 있기 때문에 항상 조인한 결과값에 중복값이 있는지 잘 확인해야 한다.

예를 들어보자.


TABLE A와 TABLE B를 조인해서 각 PROD_ID에 PROD_P를 붙이고 싶다고 한다면 쿼리는 아래와 같다.



SELECT A.*, B.PROD_P FROM TABLE A A

LEFT JOIN TABLE B B

ON A.PORD_ID=B.PROD_ID


그러면 결과는 이렇게 깔끔하게 나올 것이다. (중복값이 없으니 당연)


그런데 만약 TABLE B에 중복값이 있다면 어떻게 될까?




TABLE B에 PROD_ID가 4인 데이터가 2개가 있다. 만약 이걸 위와 동일하게 LEFT JOIN을 한다면 결과는 PROD_ID=4인 컬럼이 중복되어서 나올 것이다.



KEY값인 PROD_ID가 1:N의 관계, 즉 붙이려는 테이블의 KEY값이 중복 데이터를 갖고 있기 때문에 이런 현상이 발생한 것이다. 중복값을 제거하는 방법은 간단하다.


1. DISTINCT 사용하기

DISTINCT는 주로 데이터 양이 적을 때 사용하는 것을 권장한다.



SELECT A.* FROM TABLE A A

LEFT JOIN (SELECT DISTINCT PROD_ID, PROD_P FROM TABLE B) B

ON A.PROD_ID=B.PROD_ID



참고로 DISTINCT를 하면 중복된 컬럼 중 가장 첫번째 값을 갖고 오기 때문에 내가 붙이고자 하는 조건이 어떤 것이냐에 따라서 DISTINCT 외에 다른 구문을 사용해야 할 수도 있다. 만약 위의 경우에서 가격이 가장 작은 것을 붙이고 싶다면 MIN(PROD_P)를, 가격이 가장 큰 것을 붙이고 싶다면 MAX(PROD_P)를 사용하면 된다.



2. GROUP BY 사용하기

SELECT A.* FROM TABLE A A

LEFT JOIN (SELECT * FROM TABLE B GROUP BY PROD_ID, PROD_P HAVING MAX(PROD_P)) B

ON A.PROD_ID=B.PROD_ID

ORDER BY A.PROD_ID --PROD_ID가 TABLE A와 TABLE B에 모두 있으므로 ANSI 명시 필수




#오라클 #sql #leftjoin #leftjoin중복제거