Приветствую Вас на сайте Info-Comp.ru! В данном материале я расскажу Вам о том, как реализовать соединение FULL JOIN в MySQL, т.е. чем его можно заменить, ведь в данной СУБД этот тип соединения не поддерживается.
Соединения JOIN в SQL
В SQL для объединения данных нескольких таблиц используется секция JOIN оператора SELECT, при этом существует несколько типов такого соединения таблиц.
Заметка! Что такое SQL. Назначение и основа.
FULL JOIN – это своего рода соединение и LEFT, и RIGHT, которое применили в одном запросе.
К сожалению, в MySQL данный тип соединения не поддерживается, возможно, потому, что разработчики считают его немного избыточным, хотя во всех других популярных СУБД, например, в Microsoft SQL Server или в PostgreSQL, соединение FULL JOIN реализовано. С другой стороны, на практике действительно соединение FULL JOIN требуется достаточно редко.
Заметка! ТОП 5 популярных систем управления базами данных (СУБД).
Однако данное соединение все-таки может потребоваться, поэтому в данном материале я расскажу, как его реализовать в MySQL.
Реализуем FULL JOIN в MySQL
Реализовать FULL JOIN на самом деле достаточно просто, ведь, как было уже отмечено ранее, это по сути объединённое соединение LEFT и RIGHT. Поэтому, чтобы получить точно такой же результат, как и при соединении FULL JOIN, мы должны объединить два результирующих набора данных, в одном использовать LEFT JOIN, а в другом RIGHT JOIN.
Для объединения нескольких результирующих наборов в SQL используются операторы UNION и UNION ALL. Именно их мы и будем использовать.
Исходные данные для примера
Чтобы было наглядно видно, как работает соединение FULL JOIN, давайте создадим тестовые данные, в частности две таблицы, данные которых мы и будем объединять с помощью FULL JOIN.
Давайте представим, что у нас есть таблица с товарами, а также таблица с категориями товаров:
- products – товары;
- categories – категории товаров.
В таблице с товарами будет ссылка на таблицу с категориями, при этом у нас будут товары, для которых категория еще не определена, кроме этого в таблице с категориями у нас будут категории, в которых нет еще ни одного товара.
Инструкция для создания таких данных.
-- Создание таблицы с товарами CREATE TABLE products ( product_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, category INT NULL, product_name VARCHAR(100) NOT NULL ); -- Создание таблицы с категориями CREATE TABLE categories ( category_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, category_name VARCHAR(100) NOT NULL ); -- Добавление данных в таблицу с товарами INSERT INTO products(category, product_name) VALUES (1, 'Системный блок'), (1, 'Монитор'), (2, 'Холодильник'), (2, 'Телевизор'), (NULL, 'Операционная система'); -- Добавление данных в таблицу с категориями INSERT INTO categories (category_name) VALUES ('Комплектующие компьютера'), ('Бытовая техника'), ('Мобильные устройства'); SELECT * FROM products; SELECT * FROM categories;
Таблица products
Таблица categories
Заметка! Установка MySQL 8 на Windows 10.
Соединение LEFT JOIN и RIGHT JOIN
Теперь давайте посмотрим, как будет происходить объединение данных при помощи LEFT JOIN и RIGHT JOIN.
LEFT JOIN
SELECT p.product_name, c.category_name FROM products p LEFT JOIN categories c ON p.category = c.category_id;
Как видим, у нас вывелись все записи из таблицы с товарами, а у товаров, у которых категория еще не определена, из таблицы categories вывелось значение NULL.
RIGHT JOIN
Теперь изменим LEFT на RIGHT и посмотрим на результат.
SELECT p.product_name, c.category_name FROM products p RIGHT JOIN categories c ON p.category = c.category_id;
В данном случае у нас вывелись все записи из таблицы с категориями, а рядом с теми категориями, в которых нет ни одного товара, в столбцах из таблицы товаров вывелось значение NULL.
Как Вы понимаете, в первом случая с LEFT JOIN мы не видим категории, в которых нет еще товаров, а во втором с RIGHT JOIN, мы не видим товары, не относящиеся ни к одной категории.
FULL JOIN
Теперь представим, что нам потребовалось сформировать такие данные, чтобы было видно и товары без категорий и категории без единого товара.
В других СУБД мы могли бы легко заменить LEFT или RIGHT на FULL и тем самым получили бы тот результат, который нам нужен.
SELECT p.product_name, c.category_name FROM products p FULL JOIN categories c ON p.category = c.category_id;
Пример FULL JOIN в Microsoft SQL Server (те же самые данные)
Заметка! Если Вас интересует язык SQL, то рекомендую почитать книгу «SQL код» – это самоучитель по языку SQL для начинающих программистов. В ней очень подробно рассмотрены основные конструкции языка.
Теперь мы видим, какие товары без категорий, и какие категории без товаров.
Давайте попробуем реализовать то же самое, но в MySQL.
Реализация FULL JOIN в MySQL с помощью UNION
Как было уже отмечено ранее, мы можем реализовать FULL JOIN, объединив два запроса при помощи UNION, в первом мы будем использовать LEFT JOIN, а во втором RIGHT JOIN.
По факту мы берем те же самые запросы, которые мы использовали чуть ранее, и объединяем их с помощью UNION.
SELECT p.product_name, c.category_name FROM products p LEFT JOIN categories c ON p.category = c.category_id UNION SELECT p.product_name, c.category_name FROM products p RIGHT JOIN categories c ON p.category = c.category_id;
Как видим, мы получили точно такой же результат, как и в случае с FULL JOIN.
Реализация FULL JOIN в MySQL с помощью UNION ALL
Как Вы, наверное, знаете, запросы с UNION выполняются достаточно медленно, за счет сортировки и удаления дублирующих строк.
Чтобы немного увеличить производительность, мы можем использовать оператор UNION ALL. Однако он выведет все данные двух запросов, что приведет к наличию дублированных строк, но это мы можем легко исправить, если во втором запросе с RIGHT JOIN мы поставим условие, которое уберет повторяющиеся строки, и в итоге мы получим тот же самый результат.
SELECT p.product_name, c.category_name FROM products p LEFT JOIN categories c ON p.category = c.category_id UNION ALL SELECT p.product_name, c.category_name FROM products p RIGHT JOIN categories c ON p.category = c.category_id WHERE p.category IS NULL;
Заметка! Ошибка в MySQL Workbench «Error Code: 1175». Причины и как исправить.
На сегодня это все, надеюсь, материал был Вам полезен, пока!