본문 바로가기

Back-End 공부/Database

[Database] 테이블 JOIN 종류와 사용 방법

JOIN

 

조인(JOIN) 

  • 여러 테이블에서 가져온 레코드를 조합하여 하나의 테이블이나 결과 집합으로 표현
  • 크게는 INNER JOIN, OUTER JOIN으로 구분

 

✅  종류

출처 : 네이버

 

 

- INNER JOIN

출처 : TEMOK

  • Table1 INNER JOIN Table2 ON Table1.Products = Table2.Products;
  • 두 테이블 사이에 지정된 조건에 맞는 레코드만을 반환
  • 가장 일반적인 형태
  • INNER를 생략하고 JOIN만 쓰면 INNER JOIN으로 실행됨

 

 

- LEFT JOIN = LEFT OUTER JOIN

  • Table1 LEFT JOIN Table2 ON Table1.Products = Table2.Products; => 왼쪽 테이블이 기준이 됨
  • 왼쪽 데이터를 기준으로 오른쪽 데이터 붙이기
  • 왼쪽 테이블 데이터는 모두  출력
  • 왼쪽 테이블에 있는 값이 오른쪽 테이블에 있다면 오른쪽 테이블에 있는 값을 붙여서 출력
  • 왼쪽 테이블에 있는 값이 오른쪽 테이블에 없다면 null로 출력
  • TABLE 1에서 Products가 Tomatoes인 데이터가 TABLE 2에는 없기 때문에 Tomatoes의 Quantitiy는 Null 출력

 

 

- RIGHT JOIN = RIGHT OUTER JOIN

  • Table1 RIGHT JOIN Table2 ON Table1.Products = Table2.Products; => 오른쪽 테이블이 기준이 됨
  • 오른쪽 데이터를 기준으로 왼쪽 데이터 붙이기
  • 오른쪽 테이블 데이터는 모두  출력
  • 오른쪽 테이블에 있는 값이 오른쪽 테이블에 있다면 왼쪽 테이블에 있는 값을 붙여서 출력
  • 오른쪽 테이블에 있는 값이 왼쪽 테이블에 없다면 null로 출력
  • TABLE 2에서 Products가 Broccoli인 데이터가 TABLE 1에는 없기 때문에 Broccoli의 Price는 Null 출력

 

 

- OUTER JOIN

  • Table1 OUTER JOIN Table2 ON Table1.Products = Table2.Products;

 

출처 : PLAYDATA

 

  • 고객정보 OUTER JOIN 도시 ON 고객정보.도시코드 = 도시.도시코드 ;
  • 왼쪽 테이블과 오른쪽 테이블에 있는 데이터 모두 붙이기
  • 왼쪽 테이블에는 존재하고 오른쪽 테이블에는 존재하지 않는 컬럼값, 오른쪽 테이블에는 존재하고 왼쪽 테이블에는 존재하지 않는 컬럼값 모두 NULL로 출력
  • A LEFT (OUTER) JOIN B의 결과와 A RIGHT (OUTER) JOIN B의 결과를 합친 것(UNION)과 같음

 

 

 

💻 INNER JOIN 실습 
  • author의 id와 post의 author_id가 일치하는 ON 조건을 만족하는 데이터만 JOIN
 
select * from author;
select * from post;

SELECT * FROM author INNER JOIN post ON author.id = post.author_id;
 

 

author 테이블
post 테이블

 

INNER JOIN 결과

 

author의 id와 post의 author_id가 일치하는 ON 조건을 만족하는 데이터만 출력되었다.

 

 

 

💻 LEFT JOIN 실습 
  • author의 테이블은 일단 다 조회, author가 작성한 글 정보를 join 추가적으로 조회

LEFT JOIN 결과

author 테이블의 데이터는 모두  출력

author 테이블에 있는 값이 post에도 있다면 붙여서 출력, 없다면 null로 출력

 

 

 

💻 JOIN 실습(INNER JOIN, LEFT JOIN)

 

(1) author 테이블과 post 테이블을 JOIN하여, 글을 작성한 모든 저자의 이름과 해당 글의 제목을 조회하시오.author는 alias a, post는 alias p를 쓰시오

 
SELECT name, title FROM author AS a INNER JOIN post AS p ON a.id = p.author_id;
 

 

 

 

(2) author 테이블을 기준으로 post 테이블과 JOIN하여, 모든 저자의 이름과 해당 저자가 작성한 글의 제목을 조회하시오. 글을 작성하지 않은 저자의 경우, 글 제목은 NULL로 표시

 
SELECT name, title FROM author AS a LEFT JOIN post AS p ON a.id = p.author_id;
 

 

 

(3) 위 예제와 동일하게 모든 저자의 이름과 해당 저자가 작성한 글의 제목을 조회. 단, 저자의 나이가 25세 이상인 저자만 조회

 
SELECT name, title, age FROM author AS a LEFT JOIN post AS p ON a.id = p.author_id WHERE a.age>=25;
 

결과 확인을 위해 age 필드 추가

 

 

 

💻 프로그래머스 문제 풀기

 

(1) 없어진 기록 찾기

https://rookie-programmer.tistory.com/140

 

[SQL] 없어진 기록 찾기

⭐ 문제 천재지변으로 인해 일부 데이터가 유실되었습니다. 입양을 간 기록은 있는데, 보호소에 들어온 기록이 없는 동물의 ID와 이름을 ID 순으로 조회하는 SQL문을 작성해주세요. ⭐ 구현 및 결

rookie-programmer.tistory.com

 

(2) 조건에 맞는 도서와 저자 리스트 출력하기

https://rookie-programmer.tistory.com/139

 

[SQL] 조건에 맞는 도서와 저자 리스트 출력하기

⭐ 문제 '경제' 카테고리에 속하는 도서들의 도서 ID(BOOK_ID), 저자명(AUTHOR_NAME), 출판일(PUBLISHED_DATE) 리스트를 출력하는 SQL문을 작성해주세요.결과는 출판일을 기준으로 오름차순 정렬해주세요. ⭐

rookie-programmer.tistory.com

 

 

 

✅  집합 연산자

- UNION

출처 : 티스토리

 

  • SELECT 컬럼1, 컬럼2 FROM TABLE1 UNION SELECT 컬럼1, 컬럼2 FROM TABLE2;
  • 여러 개의 SELECT 문의 결과를 하나의 테이블이나 결과 집합으로 표현
  • 각각의 SELECT 문으로 선택된 필드의 개수와 타입은 모두 일치해야함
  • UNION은 DISTINCT 키워드를 따로 명시하지 않아도 중복되는 레코드를 제거
    • 중복되는 레코드까지 모두 출력하고 싶다면 UNION ALL

 

- INTERSECT(교집합), MINUS(차집합)

참고 : https://donzbox.tistory.com/110

연산자  의 미  결   과 
 UNION 합집합  중복을 제거한 결과의 합을 검색
 UNION ALL  중복을 포함한 결과의 합을 검색
 INTERSECT 교집합  양쪽 모두에서 포함된 행을 검색
 MINUS 차집합  첫 번째 검색 결과에서 두 번째 검색 결과를 제외한 행을 검색 

 

 

 

💻 UNION 실습

 

(1) author 테이블에서 name, email post 테이블에서 title, contents UNION하기

SELECT name, email FROM author UNION SELECT title, contents FROM post;

 

 

(2) author 테이블에서 name, email post 테이블에서 title, contents UNION ALL하기

중복된 행이 없기 때문에 위의 결과과 동일

 

 

✅  서브쿼리

 

  • 다른 쿼리 내부에 포함되어 있는 SELECT 문을 의미
  • JOIN대신 서브쿼리를 써보자
    • SELECT a.* FROM author a INNER JOIN post p ON a.id = p.author_id; 
    • SELECT a.* FROM author a WHERE a.ID IN (SELECT p.author_id FROM post p);
  • IN과 NOT IN을 많이 사용
    • SELECT * FROM tableA WHERE id IN (SELECT a_id FROM tableB);
    • 서브쿼리는 반드시 괄호(())로 감싸져 있어야 한다
  • 대부분의 서브쿼리는 join으로 대체가능하고 join을 쓰는것이 성능이 더 좋음
    • 단, 매우 복잡한 쿼리는 join으로 대체하는 것이 불가능