개요
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?