FULL OUTER JOIN

На практике я столкнулся с ситуацией, когда нужно было выбрать данные из двух связанных сущностей при помощи полного соединения. К сожалению, MySQL пока не поддерживает FULL OUTER JOIN. Ниже приведен пример эмуляции этого вида JOIN. Задача: у нас есть 2 сущности (1 — авторы книг, 2 — сами книги), книга может не иметь автора (допустим, Библия). Нам нужно выбрать всех авторов с их книгами (при чем, если у автора нет книг, то его нужно выбрать тоже). Таблица author.

CREATE TABLE author(
    id BIGINT (20) UNSIGNED NOT NULL AUTO_INCREMENT,
    name VARCHAR (20) NOT NULL,
    PRIMARY KEY (id)
);
INSERT INTO author (name) VALUES ('Виктор Пелевин');
INSERT INTO author (name) VALUES ('Лама Оле Нидал');
INSERT INTO author (name) VALUES ('Иван Иванов');

Таблица book.

CREATE TABLE book(
    id BIGINT (20) UNSIGNED NOT NULL AUTO_INCREMENT,
    author_id BIGINT (20) UNSIGNED DEFAULT NULL,
    title VARCHAR (20) DEFAULT NULL,
    PRIMARY KEY (id)
)
INSERT INTO book (author_id, title) VALUES (1, 'Чапаев и пустота');
INSERT INTO book (author_id, title) VALUES (1, 'Generation P');
INSERT INTO book (author_id, title) VALUES (2, 'Будда и любовь');
INSERT INTO book (author_id, title) VALUES (NULL, 'Библия');

Эмуляцию FULL OUTER JOIN сделаем при помощи совместного использования LEFT JOIN и RIGHT JOIN.

SELECT
    a.name,
    b.title
FROM
    author AS a
LEFT JOIN
    book AS b
    ON a.id = b.author_id
UNION
SELECT
    a.name,
    b.title
FROM
    author AS a
RIGHT JOIN
    book AS b
    ON a.id = b.author_id

В итоге мы получим следующие данные.

name title
Виктор Пелевин Чапаев и пустота
Виктор Пелевин Generation P
Лама Оле Нидал Будда и любовь
Иван Иванов NULL
NULL Библия