반응형

SQL에서 JOIN이라는 중요한 하나의 툴을 제공한다. JOIN은 서로 다른(혹은 자기 자신도 포함하는) 테이블을 가지고 합치는 등의 연산(?)을 수행하는 하나의 방법이다. 실제로 데이터를 다루다보면 합쳐야 하는 경우가 생기기 마련이다.

 

SQL에서는 JOIN에 대한 여러가지 방법을 제공하는데, 여기선 INNER JOIN, LEFT(RIGHT) JOIN, FULL JOIN 세 가지를 다뤄보고자 한다. LEFT와 RIGHT는 표면상으로 다르긴 하지만, 작동방식은 반대로만 생각하면 되기 때문에 사실은 유사한 JOIN이라고 할 수 있다. 이는 후에 설명하도록 하겠다.

 

SQL 스크립트를 들어가기 전에, 간단히 상황 설명을 하자면 아래와 같다.

  •  두개의 테이블이 존재: countries, currencies
  • 지역이 'North America'이거나 없는(NULL) 경우에 대해서만 찾아보기
  • 두 테이블 사이 연관되는 것은 나라 코드(code)
  • 나라이름(name), 나라코드(code), 지역(region), 화폐단위(basic_unit)을 조회

 

이것을 명심한 상태로 각각의 JOIN에 대해 살펴보자. 첫번째로, FULL JOIN이다. 이름에서 알 수 있다시피 FULL JOIN은 모든 것을 포함한다는 뜻이다. 이를 집합을 이용해 설명하자면, 합집합의 형태이다.

 

하나의 키로 기준을 보면, countries 테이블에만 있는 것도 있고 currencies 테이블에만 있는 것도 있기 마련이다. 앞에서 말했던 내용 JOIN들은 한쪽에만 있거나 겹치는 경우만 출력한다. 하지만, FULL JOIN에서는 두 테이블에 있는 내용들을 전부 출력하는데 사용할 수 있다. 따라서, 서로의 테이블에 없는 경우가 출력되는 경우도 있는데 그럴 경우에는 NULL값이 나온다.

 

SELECT name AS country, code, region, basic_unit
-- 3. From countries
FROM countries
  -- 4. Join to currencies
  FULL JOIN currencies
    -- 5. Match on code
    USING (code)
-- 1. Where region is North America or null
WHERE region = 'North America' OR region IS NULL
-- 2. Order by region
ORDER BY region;

한 가지 덧붙이자면, 조건에 대해 사용하는 코드가 ON table A.key = table B.key 를 사용하는 게 일반적이다. 하지만, 교집합을 찾아줄 수 있는 key가 같다면, USING을 이용해서 훨씬 코드의 길이를 줄일 수 있다.

 

 

다음은 LEFT JOIN이다. 이는 원래 SELECT문의 테이블을 왼쪽으로 두고, 오른쪽에 LEFT JOIN 다음에 오는 테이블을 두는 형태이다. (RIGHT JOIN은 그 반대) 이런 LEFT JOIN은 집합의 관점에서 봤을 때, 차집합이다. 즉, 위 FULL JOIN에서 countries에 null 값이 나오는 것을 제외하는 개념이다.

 

SELECT name AS country, code, region, basic_unit
-- 1. From countries
FROM countries
  -- 2. Join to currencies
  LEFT JOIN currencies
    -- 3. Match on code
    USING (code)
-- 4. Where region is North America or null
WHERE region = 'North America' OR region IS NULL
-- 5. Order by region
ORDER BY region;​

 

 

마지막으로는 INNER JOIN인데, 이를 집합의 관점에서 보자면 교집합과 같다. 즉, 두개의 테이블이 code란 공통점을 가지고 겹치는 부분만을 조회하게 해준다는 것이다. 위 LEFT JOIN에서 countries에서 가져온 필드 값들이 null이 나온 경우를 제외한 거라면, INNER JOIN에서는 여기다가 currencies에서 가져온 필드가 null이 나온 경우까지 제외한다.

 

그러다보니, 조회되는 데이터의 수는 가장 적을 수 밖에 없다. (데이터의 개수: FULL >= LEFT(RIGHT) >= INNER)

SELECT name AS country, code, region, basic_unit
FROM countries
  -- 1. Join to currencies
  INNER JOIN currencies
    USING (code)
-- 2. Where region is North America or null
WHERE region = 'North America' OR region IS NULL
-- 3. Order by region
ORDER BY region;

 

 

 

지금까지 얘기한 것을 그림으로 종합하면, 아래처럼 종합할 수 있다. 내가 만든 그림은 아니지만, JOIN에 대해서 꽤 잘 설명되어 있다고 생각해서 가져왔으므로 쓰고자 하는 형태에 따라서 맞춰서 사용하면 된다.

 

 

이미지 참고: https://postitforhooney.tistory.com/entry/DBMARIADB-SQL-%EC%98%88%EC%A0%9C%EB%A5%BC-%ED%86%B5%ED%95%9C-JOIN%EC%9D%98-%EC%A2%85%EB%A5%98-%ED%8C%8C%EC%95%85

반응형