도서/모두를 위한 postgreSQL

Day13. 여러 개의 테이블을 컬럼으로 연결하기

joje* 2023. 8. 13. 13:15

1. FROM 절과 WHERE절을 이용한 데이터 결합

  • 두 개의 테이블을 모두 FROM 절에 불러오는 의미 = CROSS JOIN을 한다는 의미이다.
  • CROSS JOIN이란 두 테이블의 각각의 로우가 서로 한 번씩 결합시키는 것을 의미한다.
  • 따라서, SELECT * FROM rating,ramen; 쿼리문은 SELECT * FROM rating CROSS JOIN ramen; 쿼리문을 실행시키는 것과 같다

2. WHERE 절로 결합된 데이터 고르기

: FROM 절로 두 개의 테이블을 결합한 데이터베이스에 WHERE절을 사용하면, 결합된 데이터에서 필요한 정보만 걸러내어 가져올 수 있다.

  • SELECT rating.user_id, rating.rating, ramen.name, ramen.quantity, ramen.is_spicy FROM rating, ramen WHERE ramen.id = rating.item_id  AND rating.item_type = 'ramen';

3. JOIN을 이용한 데이터 결합

: JOIN 문 결합 시 FROM 절에 JOIN을 명시적으로 표시해주고, WHERE 대신 ON을 적어주어 두 테이블이 결합할 수 있도록 한다.

: 즉, 아래 두 쿼리문은 결과 및 성능이 완전히 동일하다. 

  • SELECT rating.user_id, rating.rating, ramen.name, ramen.quantity, ramen.is_spicy FROM rating, ramen WHERE ramen.id = rating.item_id  AND rating.item_type = 'ramen';
  • SELECT rating.user_id, rating.rating, ramen.name, ramen.quantity, ramen.is_spicy FROM (rating JOIN ramen ON ramen.id = rating.item_id  AND rating.item_type = 'ramen');

** EXPLAIN을 붙여 해당 쿼리의 실행계획을 확인하면 동일함을 명식적으로 알 수 있다.

  • EXPLAIN SELECT rating.user_id, rating.rating, ramen.name, ramen.quantity, ramen.is_spicy FROM rating, ramen WHERE ramen.id = rating.item_id  AND rating.item_type = 'ramen';
  • EXPLAIN  SELECT rating.user_id, rating.rating, ramen.name, ramen.quantity, ramen.is_spicy FROM (rating JOIN ramen ON ramen.id = rating.item_id  AND rating.item_type = 'ramen');

4. 다양한 JOIN의 종류

: JOIN 문은 크게 내부 JOIN문과 외부 JOIN문으로 나뉜다. 내부 JOIN문은 두 테이블 값이 서로 연결되는 부분만 결과로 출력하고, 외부 JOIN 문은 서로 연결되지 않고 한쪽에만 데이터가 있는 로우도 출력된다.

: 자주 사용되는 JOIN문의 종류는 아래와 같다.

4.1 LEFT JOIN, RIGHT JOIN

: 명령어 앞에 쓰인 테이블을 기준으로 뒤에 쓰인 테이블과 연결되는 정보만 불러오고, 만약 연결된 정보가 없다면 NULL 값으로 출력한다.

: RIGHT JOIN 명령어는 반대로 뒤에 적힌 테이블을 기준으로 정보를 출력한다.

: ramen과 rating 2개의 테이블을 이용해 아래와 같이 LEFT JOIN, RIGHT JOIN 쿼리문을 실행한 결과는 다음과 같다.

<rating 테이블 데이터>

 

<ramen 테이블 데이터>

  • SELECT rating.user_id, rating.rating, ramen.name, ramen.quantity, ramen.is_spciy FROM ( rating LEFT JOIN ramen ON ramen.id = rating.item_id AND rating.item_type = 'ramen');
  • 왼쪽 테이블(rating)을  기준으로 오른쪽 테이블에 값이 없는 경우, null 값을 자동으로 넣어 빈 칸으로 표시한다.

<LEFT JOIN 결과>

  • SELECT rating.user_id, rating.rating, ramen.name, ramen.quantity, ramen.is_spicy FROM (rating RIGHT JOIN ramen ON ramen.id = rating.user_id AND rating.item_type = 'ramen');
  • 오른쪽 테이블(ramen)을  기준으로 왼쪽 테이블에 값이 없는 경우, null 값을 자동으로 넣어 빈 칸으로 표시한다.

<RIGHT JOIN 결과>

4.2 FULL JOIN

: FULL JOIN의 경우 서로 연결된 로우는 서로 연결해 출력하고, 서로 연결되지 않은 로우는 연결되지 않은 부분의 정보를 NULL 값으로 비워둔 채 출력한다.

  • SELECT rating.user_id, rating.rating, ramen.name, ramen.quantity, ramen.is_spicy FROM( rating FULL JOIN ramen ON ramen.id = rating.user_id AND rating.item_type = 'ramen');

<FULL JOIN 결과>

 

5. JOIN문이 사용되는 위치

: JOIN문은 일반적으로 FROM절 다음에 위치하게 된다.

: JOIN문이 2개 사용되는 경우, 쿼리의 구조가 헷갈리므로, JOIN 문 앞,뒤로 각각의 테이블이 온다는 점을 기억하고 괄호를 적어주면 좀 더 이해가 쉽다.

  • SELECT users.name, ramen.name, rating.rating, ramen.quantity, ramen.is_spicy
  • FROM rating JOIN ramen
  • ON ramen.id = rating.item_id AND rating.item_type = 'ramen'
  • JOIN users
  • ON users.id = rating.user_id
  • WHERE rating >= 3;

:위와 같이 적는 것 보다 아래와 같이 적는 게 좀 더 직관적으로 이해할 수 있다.

  • SELECT users.name, ramen.name, rating.rating, ramen.quantity, ramen.is_spicy
  • FROM (
  •   (
  •     rating JOIN ramen
  •     ON ramen.id = rating.item_id AND rating.item_type = 'ramen'
  •   ) JOIN users
  •   ON users.id = rating.user_id
  • )
  • WHERE rating >= 3;

6. JONI문 뒤에 오는 명령어

: JOIN 문 뒤에는 ON 명령어나 USING 명령어가 주로 붙는다. ON 명령어 뒤에는 테이블을 연결하는 조건을 적어주고, USING 명령어 뒤에는 두 테이블을 연결할 공통된 컬럼 이름을 적어준다.

: USING의 경우, 두 테이블의 공통된 컬럼이 있을 때만 사용이 가능하다.

  •  테이블 JOIN  테이블 ON 연결할 조건
  •  테이블 JOIN 테이블 USING (연결할 컬럼 목록)

<ON 조건문을 사용>

 

<USING 조건문을 사용>