Database

[MySQL] JOIN/UNION을 사용한 FULL OUTER JOIN

비번변경 2022. 12. 8. 17:39

개요

2022.06.12 - [MySQL] JOIN에서 정리했지만 MySQL에서는 FULL OUTER JOIN을 지원하지 않는다. 하지만 OUTER JOIN과 UNION을 이용하면 FULL OUTER JOIN을 할 수 있다.

 

 

SQL

SQL은 다음과 같은 구조이다.

2개 테이블 JOIN

SELECT * 
FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.id
UNION
SELECT * 
FROM t1 RIGHT OUTER JOIN t2 ON t1.id = t2.id

 

3개 테이블 JOIN

SELECT * FROM t1
LEFT OUTER JOIN t2 ON t1.id = t2.id
LEFT OUTER JOIN t3 ON t2.id = t3.id
UNION
SELECT * FROM t1
RIGHT OUTER JOIN t2 ON t1.id = t2.id
LEFT OUTER JOIN t3 ON t2.id = t3.id
UNION
SELECT * FROM t1
RIGHT OUTER JOIN t2 ON t1.id = t2.id
RIGHT OUTER JOIN t3 ON t2.id = t3.id

 

 

예시

아래와 같이 person_1, person_2 테이블이 존재한다고 하자.

-- person_1
| id |  name |
|----|-------|
|  1 |   Tim |
|  2 | Marta |

--person_2
| id |     name |
|----|----------|
|  1 |      Tim |
|  3 | Katarina |

DDL은 접은 글로 남겨둔다.

더보기
--DDL
CREATE TABLE IF NOT EXISTS `person_1`(
  `id` int(6) unsigned NOT NULL,
  `name` varchar(200) NOT NULL,
  PRIMARY KEY (`id`,`name`)
) DEFAULT CHARSET=utf8;
INSERT INTO `person_1` (`id`, `name`) VALUES
  (1, 'Tim'),
  (2, 'Marta');

CREATE TABLE IF NOT EXISTS `person_2`(
  `id` int(6) unsigned NOT NULL,
  `name` varchar(200) NOT NULL,
  PRIMARY KEY (`id`,`name`)
) DEFAULT CHARSET=utf8;
INSERT INTO `person_2` (`id`, `name`) VALUES
  (1, 'Tim'),
  (3, 'Katarina');

 

두 개의 테이블을 INNER JOIN 하면 아래와 같이 테이블 모두에 포함된 데이터만 얻을 수 있다.

SELECT *
FROM person_1 AS p1
JOIN person_2 AS p2
ON p1.id = p2.id
;

-- 실행 결과
| id | name | id | name |
|----|------|----|------|
|  1 |  Tim |  1 |  Tim |

 

각 테이블에 모두 포함되지 않은 데이터를 얻기 위해 LEFT OUTER JOIN, RIGHT OUTER JOIN을 하면 다음과 같다.

SELECT *
FROM person_1 AS p1
LEFT OUTER JOIN person_2 AS p2
ON p1.id = p2.id
;

SELECT *
FROM person_1 AS p1
RIGHT OUTER JOIN person_2 AS p2
ON p1.id = p2.id
;


-- 실행 결과
| id |  name |     id |   name |
|----|-------|--------|--------|
|  1 |   Tim |      1 |    Tim |
|  2 | Marta | (null) | (null) |

|     id |   name | id |     name |
|--------|--------|----|----------|
|      1 |    Tim |  1 |      Tim |
| (null) | (null) |  3 | Katarina |

 

두 결과를 UNION으로 합치면 아래와 같이 FULL OUTER JOIN과 같은 결과를 얻을 수 있다.

SELECT *
FROM person_1 AS p1
LEFT OUTER JOIN person_2 AS p2
ON p1.id = p2.id
UNION
SELECT *
FROM person_1 AS p1
RIGHT OUTER JOIN person_2 AS p2
ON p1.id = p2.id 
;

-- 실행 결과
|     id |   name |     id |     name |
|--------|--------|--------|----------|
|      1 |    Tim |      1 |      Tim |
|      2 |  Marta | (null) |   (null) |
| (null) | (null) |      3 | Katarina |

 

+ 중복 컬럼이 신경 쓰인다면 SELECT 시 조회할 Column을 선택하도록 한다. 다만 JOIN 조건에 NULL이 나오지 않도록 OUTER JOIN의 기준 테이블의 Column을 조회하도록 신경 써야 한다.

SELECT p1.id, p1.name
FROM person_1 AS p1
LEFT OUTER JOIN person_2 AS p2
ON p1.id = p2.id
UNION
SELECT p2.id, p2.name
FROM person_1 AS p1
RIGHT OUTER JOIN person_2 AS p2
ON p1.id = p2.id 
;

-- 실행 결과
| id |     name |
|----|----------|
|  1 |      Tim |
|  2 |    Marta |
|  3 | Katarina |

 

 

참고 문서

Why does MySQL report a syntax error on FULL OUTER JOIN?

How can I do a FULL OUTER JOIN in MySQL?

https://sdr1982.tistory.com/246