본문 바로가기

진리는어디에

[MySQL] 조인(Join) 쿼리

조인(Join)의 개념

조인은 여러개의 테이블을 결합하여 데이터를 검색 하는 것입니다. 예를 들어 A와 B라는 테이블을 따로 select하는 것이 아니라 동시에 select를 한다고 생각하시면 됩니다. 그 결과 중 특정 컬럼들의 값을 비교해서 같은 것들(혹은 다른 것들)만 select한다던지 하는 것을 조인이라고 합니다. where 절로 구분 하는 방법에 따라 여러가지 이름으로 불리고 있지만 간단한 개념이 이렇다는 것입니다.

조인(Join)의 종류

  • 연산자에 따른 분류 :
    EQUI JOIN : 테이블들의 컬럼 값들이 일치하는 경우('=' 연산자 사용)
    NON-EQUI JOIN : 테이블드릐 컬럼 값들이 일치하지 않는 경우('<', '>' 와 같은 비교 연산자 사용)
  • FROM 절의 JOIN형태에 따른 분류
    INNER JOIN : JOIN 조건에서 값이 일치하는 행만 반환
    OUTER JOIN : JOIN 조건에서 모든 테이블 조건에 만족하지 않더라도 행을 반환. 기준이 되는 테이블의 위치에 따라 LEFT JOIN, RIGHT JOIN 이 있다.
  • SELF JOIN : 동일한 테이블의 컬럼내에서 조인

아래의 예제는 조인을 설명하기 위해 임시로 만든 테이블과 데이터들입니다.

mysql> select user_seq, user_name, server_id from user_data;
+----------+------------------+------------+
| user_seq | user_name        | server_id  |
+----------+------------------+------------+
|        1 | 6cb34eada4532729 | 3232235548 |
|        2 | 1884c598ce025e8a | 3232235548 |
|        3 | ce118ec03c2afc7b | 3232235548 |
|        5 | 6369b99902693d0d | 3232235548 |
+----------+------------------+------------+
4 rows in set (0.00 sec)

mysql> select mail_seq, user_seq, expire_date, mail_message, delete_date from user_mail;
+----------+----------+---------------------+----------------------------+---------------------+
| mail_seq | user_seq | expire_date         | mail_message               | delete_date         |
+----------+----------+---------------------+----------------------------+---------------------+
|        1 |        1 | 2022-02-19 01:29:45 | "Event","한글","123","!@#" | 2021-02-19 01:29:45 |
|        2 |        2 | 2022-02-19 01:34:44 | "Event","한글","123","!@#" | 2021-02-19 01:34:44 |
|        3 |        3 | 2022-02-19 01:44:50 | "Event","한글","123","!@#" | 2021-02-19 01:45:27 |
|        4 |        4 | 2022-02-20 00:04:35 | "Event","한글","123","!@#" | 2021-02-20 00:04:35 |
|        5 |        4 | 2022-02-20 00:04:35 | "Event","한글","123","!@#" | 2021-02-20 00:04:35 |
+----------+----------+---------------------+----------------------------+---------------------+
5 rows in set (0.00 sec)
  • user_data 테이블과 user_mail 테이블 둘다 공통적으로 user_seq라는 컬럼을 가지고 있습니다.
  • user_data 테이블의 user_seq에는 4번이 없고, user_mail 테이블의 user_seq는 5번이 없습니다.
  • user_mail 테이블의 user_seq 4는 메일 데이터가 2개가 있습니다.
반응형

EQUI JOIN

조인 대상 테이블에서 공통 칼럼을 '=' 비교를 통해, 같은 값을 가지는 행을 연결하여 결과를 생성하는 조인 방법 입니다. 

예를 들기 이전에 설명의 편의를 위해 EQUI JOIN에서 테이블 간의 연결 고리가 되는 공통 칼럼을 Join Attribute라고 정의 하겠습니다. 이 Join Attribute는 참조 무결성을 가져야 하며 한쪽 컬럼의 값이 NULL일경우 조인 결과에서 제외 됩니다.

SELECT table1.column, table2.column FROM table1, table2 WHERE table1.column1 = table2.column2;

주목 할것은 : 

  • column 이름 앞에 테이블 이름으로 컬럼의 스코프를 지정 줘 스코프를 구분 했다는 것.
  • FROM 절에서 테이블이 하나가 아니라 두 개(사실 N개도 가능)를 썼다는 것.
  • WHERE에서 서로 다른 두 테이블의 컬럼을 비교 하고 있다는 것.

정도 입니다.

mysql> select a.user_seq, a.user_name, b.mail_seq, b.user_seq, b.expire_date, b.delete_date 
from user_data a, user_mail b where a.user_seq = b.user_seq;
+----------+------------------+----------+----------+---------------------+---------------------+
| user_seq | user_name        | mail_seq | user_seq | expire_date         | delete_date         |
+----------+------------------+----------+----------+---------------------+---------------------+
|        1 | 6cb34eada4532729 |        1 |        1 | 2022-02-19 01:29:45 | 2021-02-19 01:29:45 |
|        2 | 1884c598ce025e8a |        2 |        2 | 2022-02-19 01:34:44 | 2021-02-19 01:34:44 |
|        3 | ce118ec03c2afc7b |        3 |        3 | 2022-02-19 01:44:50 | 2021-02-19 01:45:27 |
+----------+------------------+----------+----------+---------------------+---------------------+
3 rows in set (0.00 sec)

user_data, user_mail 두 테이블에서 동일한 user_seq를 가진 행들만 리턴 되었음을 볼 수 있습니다.

INNER JOIN

INNER JOIN 또한 EQUI JOIN과 비슷합니다. 다만 비교 조건이 WHERE 절이 아닌 INNER JOIN 절에 들어갑니다.

mysql> select a.user_seq, a.user_name, b.mail_seq, b.user_seq, b.expire_date, b.delete_date 
from user_data a inner join user_mail b on a.user_seq = b.user_seq;
+----------+------------------+----------+----------+---------------------+---------------------+
| user_seq | user_name        | mail_seq | user_seq | expire_date         | delete_date         |
+----------+------------------+----------+----------+---------------------+---------------------+
|        1 | 6cb34eada4532729 |        1 |        1 | 2022-02-19 01:29:45 | 2021-02-19 01:29:45 |
|        2 | 1884c598ce025e8a |        2 |        2 | 2022-02-19 01:34:44 | 2021-02-19 01:34:44 |
|        3 | ce118ec03c2afc7b |        3 |        3 | 2022-02-19 01:44:50 | 2021-02-19 01:45:27 |
+----------+------------------+----------+----------+---------------------+---------------------+
3 rows in set (0.00 sec)

LEFT JOIN, RIGHT JOIN(OUTER JOIN)

LEFT JOIN과 RIGHT JOIN은 Join Attribute의 참조 무결성을 가지지 못하더라도 기준이 되는 테이블(left or right)에 따라 결과 행들을 출력합니다. LEFT JOIN시에는 왼쪽테이블에 행이 있고 그에 만족하는 오른쪽 테이블이 없다면 오른쪽 테이블의 컬럼들은 NULL값으로 출력이 됩니다.

mysql> select a.user_seq, a.user_name, b.mail_seq, b.user_seq, b.expire_date, b.delete_date 
from user_data a left join user_mail b on a.user_seq = b.user_seq;
+----------+------------------+----------+----------+---------------------+---------------------+
| user_seq | user_name        | mail_seq | user_seq | expire_date         | delete_date         |
+----------+------------------+----------+----------+---------------------+---------------------+
|        1 | 6cb34eada4532729 |        1 |        1 | 2022-02-19 01:29:45 | 2021-02-19 01:29:45 |
|        2 | 1884c598ce025e8a |        2 |        2 | 2022-02-19 01:34:44 | 2021-02-19 01:34:44 |
|        3 | ce118ec03c2afc7b |        3 |        3 | 2022-02-19 01:44:50 | 2021-02-19 01:45:27 |
|        5 | 6369b99902693d0d |     NULL |     NULL | NULL                | NULL                |
+----------+------------------+----------+----------+---------------------+---------------------+
4 rows in set (0.00 sec)

지금까지 user_mail에 user_seq 5번 행이 없었기 때문에 출력되지 않던 user_data 테이블의 user_seq 5번 행이 출력 되었습니다.

RIGHT JOIN은 그 반대 입니다.

mysql> select a.user_seq, a.user_name, b.mail_seq, b.user_seq, b.expire_date, b.delete_date 
from user_data a right join user_mail b on a.user_seq = b.user_seq;
+----------+------------------+----------+----------+---------------------+---------------------+
| user_seq | user_name        | mail_seq | user_seq | expire_date         | delete_date         |
+----------+------------------+----------+----------+---------------------+---------------------+
|        1 | 6cb34eada4532729 |        1 |        1 | 2022-02-19 01:29:45 | 2021-02-19 01:29:45 |
|        2 | 1884c598ce025e8a |        2 |        2 | 2022-02-19 01:34:44 | 2021-02-19 01:34:44 |
|        3 | ce118ec03c2afc7b |        3 |        3 | 2022-02-19 01:44:50 | 2021-02-19 01:45:27 |
|     NULL | NULL             |        4 |        4 | 2022-02-20 00:04:35 | 2021-02-20 00:04:35 |
|     NULL | NULL             |        5 |        4 | 2022-02-20 00:04:35 | 2021-02-20 00:04:35 |
+----------+------------------+----------+----------+---------------------+---------------------+
5 rows in set (0.00 sec)

user_seq 4번은 user_data 테이블에 없기 때문에 출력되지 못했지만 이번에는 기준 테이블이 right, 즉 join 절에서 오른쪽에 있던 user_mail 테이블을 기준으로 하였기 때문에 mail_seq 4, 5번 행이 출력 되었습니다.

※ 오라클에서는 양쪽 테이블에 존재하는 모든 행들을 리턴하는 FULL OUTER JOIN을 지원합니만 MySQL에서는 대신 UNION을 이용해야 합니다.

부록 1. 같이 읽으면 좋은 글

 

내용이 마음에 드셨다면 공감(❤)과 짧은 댓글 달아 주시면 더욱 좋은 내용의 글로 보답 하겠습니다. 감사합니다.

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!