본문 바로가기

필사적 필사

[MYSQL] JOIN과 UNION 문법과 개념 정리

본 게시글은 아래의 글을 필사하였습니다.

http://tcpschool.com/mysql/mysql_multipleTable_join

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

http://tcpschool.com/mysql/mysql_multipleTable_union

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com


JOIN

JOIN은 데이터베이스 내의 여러 테이블에서 가져온 레코드를 조합하여 하나의 테이블이나 결과 집합으로 표현해 줍니다. 이러한 JOIN은 보통 SELECT 문과 함께 자주 사용됩니다. 표준 SQL에서는 레코드를 조합하는 방식에 따라 JOIN을 다음과 같이 구분합니다.

  • INNER JOIN
  • LEFT JOIN
  • RIGHT JOIN

예제에서 쓰일 예시 테이블입니다.

RESERVATION

RID NAME RESERVE_DATE ROOM_NUM
1 홍길동 2021-01-05 2014
2 임꺽정 2021-02-12 918
3 장길산 2021-01-16 1208
4 홍길동 2021-03-17 504

 

CUSTOMER

UID NAME AGE ADDRESS
1 홍길동 17 서울
2 임꺽정 11 인천
3 장길산 13 서울
4 전우치 17 수원

INNER JOIN

INNER JOIN은 ON 절과 함께 사용되며, ON 절의 조건을 만족하는 데이터만을 가져옵니다.

SELECT * FROM RESERVATION INNER JOIN CUSTOMER ON RESERVATION.NAME = CUSTOMER.NAME;
SELECT * FROM RESERVATION JOIN CUSTOMER ON RESERVATION.NAME = CUSTOMER.NAME

ON 절에서는 WHERE 절에서 사용할 수 있는 모든 조건을 사용할 수 있습니다. 표준 SQL과 달리 MYSQL에서는 JOIN, INNER JOIN, CROSS JOIN이 모두 같은 의미로 사용됩니다.

실행 결과 :

RID NAME RESERVE_DATE ROOM_NUM UID NAME AGE ADDRESS
1 홍길동 2021-01-05 2014 1 홍길동 17 서울
4 홍길동 2121-03-17 504 1 홍길동 17 서울
2 임꺽정 2021-02-12 918 2 임꺽정 11 인천
3 장길산 2021-01-16 1208 3 장길산 13 서울

 

INNER JOIN 의 결과를 벤 다이어그램으로 나타내면 다음과 같습니다.

 

INNER JOIN 의 경우에는 앞서 살펴본 표준 SQL방식과는 별도로 MYSQL에서만 사용할 수 있는 방식이 따로 존재합니다. 다음 예제는 앞서 살펴본 INNER JOIN 예제와 같은 실행결과를 보여줍니다.

SELECT * FROM RESERVATION, CUSTOMER WHERE RESERVAION.NAME = CUSTOMER.NAME;

위의 예제처럼 테이블의 이름이 길거나 복잡한 경우에는 별칭(alias)을 사용하여 SQL 구문을 간략하게 할 수 있습니다.

SELECT * FROM RESERVATION AS R, CUSTOMER AS C WHERE R.NAME = C.NAME;

LEFT JOIN

LEFT JOIN은 첫 번째 테이블을 기준으로, 두 번째 테이블을 조합하는 JOIN입니다. 이 때 ON 절의 조건을 만족하지 않는 경우에는 첫 번째 테이블의 필드 값은 그대로 가져옵니다. 하지만 해당 레코드의 두 번째 테이블의 필드 값은 모두 NULL로 표시됩니다.

다음 예제는 RESERVATION 테이블의 NAME 필드를 기준으로 CUSTOMER 테이블의 NAME 필드와 일치하는 레코드만을 LEFT JOIN으로 가져온 후, 그 중에서 RESERVE_DATE 필드의 값이 2021년 02월 01일 이후인 레코드만을 선택하는 예제입니다.

SELECT * 
FROM RESERVATION LEFT JOIN CUSTOMER 
ON RESERVATION.NAME = CUSTOMER.NAME 
WHERE RESERVE_DATE > '2021-02-01';

실행 결과 :

RID NAME RESERVE_DATE ROOM_NUM UID NAME AGE ADDRESS
4 홍길동 2021-03-17 504 1 홍길동 17 서울
2 임꺽정 2021-02-12 918 2 임꺽정 11 인천

위의 예제에서 두 개의 NAME 값이 일치하면, INNER JOIN과 같이 두 테이블의 모든 필드를 그대로 가져옵니다. 하지만 두 개의 NAME 값이 일치하지 않는 경우에는 CUSTOMER 테이블의 모든 필드는 NULL로 표시됩니다.

LEFT JOIN 의 결과를 벤 다이어그램으로 나타내면 다음과 같습니다.


RIGHT JOIN

RIGHT JOIN은 LEFT JOIN 과는 반대로 두 번째 테이블을 기준으로, 첫 번째 테이블을 조합하는 JOIN입니다.

이 때 ON 절의 조건을 만족하지 않는 경우에는 두 번째 테이블의 필드 값을 그대로 가져옵니다. 하지만 해당 레코드의 첫 번째 테이블의 필드 값은 모두 NULL로 표시됩니다.

다음 예제는 CUSTOMER 테이블의 NAME 필드를 기준으로 RESERVATION 테이블의 NAME 필드와 일치하는 레코드만을 RIGHT JOIN으로 가져오는 예제입니다.

SELECT *
FROM RESERVATION RIGHT JOIN CUSTOMER
ON RESERVATION.NAME = CUSTOMER.NAME;

실행 결과 :

UID NAME AGE ADDRESS RID NAME RESERVE_DATE ROOM_NUM
1 홍길동 17 서울 1 홍길동 2021-01-05 2014
1 홍길동 17 서울 4 홍길동 2021-03-17 504
2 임꺽정 11 인천 2 임꺽정 2021-02-12 918
3 장길산 13 서울 3 장길산 2021-01-16 1208

위의 예제에서 두 개의 NAME 값이 일치하면, INNER JOIN 과 같이 두 테이블의 모든 필드를 그대로 가져옵니다. 하지만 두 개의 NAME 값이 일치하지 않는 경우에는 RESERVATION 테이블의 모든 필드는 NULL로 표시됩니다.

RIGHT JOIN 의 결과를 벤 다이어그램으로 나타내면 다음과 같습니다.

 

 


 

 

UNION

UNION은 여러 개의 SELECT 문의 결과를 하나의 테이블이나 결과 집합으로 표현할 때 사용합니다. 이 때 각각의 SELECT 문으로 선택된 필드의 개수와 타입은 모두 같아야 하며, 필드의 순서 또한 같아야 합니다.

다음 예제는 두 SELECT 문의 결과를 UNION을 이용하여 하나의 테이블로 출력하는 예제입니다.

SELECT NAME FROM RESERVATION UNION SELECT NAME FORM CUSTOMER;

실행 결과 :

NAME
홍길동
임꺽정
장길산

위의 예제에서 두 SELECT 문의 결과는 하나로 합쳐져서 출력됩니다. 이 때 두 SELECT 문의 결과에서 중복된 레코드인 '홍길동'은 한 번만 표시됩니다.


UNION ALL

위의 예제처럼 UNION은 DISTINCT 키워드를 따로 명시하지 않아도 기본적으로 중복되는 레코드를 제거합니다. 따라서 이렇게 중복되는 레코드까지 모두 출력하고 싶다면, ALL 키워드를 사용해야 합니다.

다음 예제는 두 SELECT 문의 결과를 UNION ALL을 이용하여 하나의 테이블로 출력하는 예제입니다.

SELECT NAME FROM RESERVATION UNION ALL SELECT NAME FROM CUSTOMER;

실행 결과 :

NAME
홍길동
임꺽정
장길산
홍길동
홍길동
임꺽정
장길산

위의 예제에서 두 SELECT 문의 결과는 하나로 합쳐져서 출력됩니다. 이 때 두 SELECT 문의 결과는 중복된 레코드까지 모두 표시합니다.


추가로 예시를 만들어 보았다.

2021년 2월 1일 이후의 예약을 다음의 정보들만 포함하여 확인하라.
[예약번호, 이름, 주소, 날짜, 방 번호]
SELECT R.ID, R.NAME, C.ADDRESS, R.RESERVE_DATE, R.ROOM_NUM
FROM RESERVATION AS R LEFT JOIN CUSTOMER AS C
ON R.NAME = C.NAME 
WHERE RESERVE_DATE > '2021-02-01';

 

'필사적 필사' 카테고리의 다른 글

데이터베이스 정규화와 이상현상  (2) 2021.06.16
computed와 watch  (0) 2020.04.24
Vue 인스턴스  (0) 2020.04.24
상태 | Vuex  (0) 2020.04.24
시작하기 | Vuex  (0) 2020.04.24