Руководство по SQL. LEFT JOIN.
Запрос LEFT JOIN возвращает все записи из левой таблицы, даже в том случае, если у них нет совпадений в правой. Это означает, что даже если у нас не будет совпадений в левой таблице, мы получим запись в которая будет содержать колонки со значением NULL.
Запрос с использованием LEFT JOIN имеет следующий вид:
SELECT таблица1.колонка1, таблица2.колонка2... FROM таблица1 LEFT JOIN таблицы2 ON таблицы1.общее_поле = таблица2.общее_поле;
Пример:
Предположим, что у нас есть две таблицы:
developers:
+----+-------------------+------------+------------+--------+ | ID | NAME | SPECIALTY | EXPERIENCE | SALARY | +----+-------------------+------------+------------+--------+ | 1 | Eugene Suleimanov | Java | 2 | 2500 | | 2 | Peter Romanenko | Java | 3 | 3500 | | 3 | Andrei Komarov | JavaScript | 3 | 2500 | | 4 | Konstantin Geiko | C# | 2 | 2000 | | 5 | Asya Suleimanova | UI/UX | 2 | 1800 | | 6 | Kolya Nikolaev | Javascript | 5 | 3400 | | 7 | Ivan Ivanov | C# | 1 | 900 | | 8 | Ludmila Geiko | UI/UX | 2 | 1800 | +----+-------------------+------------+------------+--------+
tasks:
+---------+-------------+------------------+------------+--------------+ | TASK_ID | TASK_NAME | DESCRIPTION | DEADLINE | DEVELOPER_ID | +---------+-------------+------------------+------------+--------------+ | 1 | Bug#123 | Fix company list | 2016-06-03 | 1 | | 2 | Bug#321 | Fix registration | 2016-06-06 | 2 | | 3 | Feature#777 | Latest actions | 2016-06-25 | 3 | +---------+-------------+------------------+------------+--------------+
Попробуем выполнить следующий запрос:
mysql> SELECT ID, NAME, TASK_NAME, DEADLINE FROM developers LEFT JOIN tasks ON developers. ID = tasks.DEVELOPER_ID;
В результате мы получим следующую таблицу:
+----+-------------------+-------------+------------+ | ID | NAME | TASK_NAME | DEADLINE | +----+-------------------+-------------+------------+ | 1 | Eugene Suleimanov | Bug#123 | 2016-06-03 | | 2 | Peter Romanenko | Bug#321 | 2016-06-06 | | 3 | Andrei Komarov | Feature#777 | 2016-06-25 | | 4 | Konstantin Geiko | NULL | NULL | | 5 | Asya Suleimanova | NULL | NULL | | 6 | Kolya Nikolaev | NULL | NULL | | 7 | Ivan Ivanov | NULL | NULL | | 8 | Ludmila Geiko | NULL | NULL | +----+-------------------+-------------+------------+
Как мы видим, мы получили все записи из таблицы developers, а поля второй таблицы для записей, у которых нет совпадений в таблице tasks, имеют значение NULL.
На этом мы заканчиваем изучение LEFT JOIN.
SQL OUTER JOIN — левое соединение, правое соединение и полное внешнее соединение
Если вы хотите узнать о SQL INNER JOIN, ознакомьтесь с руководством по SQL INNER JOIN.
Существует три вида ВНЕШНИХ СОЕДИНЕНИЙ: левое внешнее соединение, правое внешнее соединение и полное внешнее соединение. Рассмотрим каждый вид соединения более подробно.
SQL OUTER JOIN — левое внешнее соединение
Левое внешнее соединение SQL также известно как левое соединение SQL. Предположим, мы хотим соединить две таблицы: A и B. Левое внешнее соединение SQL возвращает все строки в левой таблице (A) и все совпадающие строки, найденные в правой таблице (B). Это означает, что результат левого соединения SQL всегда содержит строки в левой таблице.
Ниже показан внешний синтаксис SQL для объединения двух таблиц: table_A и table_B:
SELECT column1, column2...
ИЗ таблицы_A
LEFT JOIN table_B ON join_condition
ГДЕ row_condition
SQL OUTER JOIN — пример левого внешнего соединения
Следующий запрос выбирает всех клиентов и их заказы:
SELECT c.customerid,
c.companyName,
номер заказа
ОТ клиентов c
LEFT JOIN заказы o ON o. customerid = c.customerid
ORDER BY orderid
Перечислены все строки в таблице клиентов . В случае, если в таблице заказов нет соответствующей строки для строки в клиентов , столбец orderid в таблице заказов заполняется значениями NULL.
Мы можем использовать диаграмму Венна, чтобы визуализировать, как работает SQL LEFT OUTER JOIN.
ВНЕШНЕЕ СОЕДИНЕНИЕ SQL — правое внешнее соединение
Правое внешнее соединение SQL возвращает все строки в правой таблице и все соответствующие строки, найденные в левой таблице. Синтаксис правого внешнего соединения SQL следующий:
SELECT столбец1, столбец2... ИЗ таблицы_A ПРАВОЕ СОЕДИНЕНИЕ table_B ON join_condition ГДЕ row_condition
Правое внешнее соединение SQL также известно как правое соединение SQL.
SQL OUTER JOIN – пример правого внешнего соединения
Следующий пример демонстрирует правое внешнее соединение SQL:
SELECT c. customerid,
c.companyName,
номер заказа
ОТ клиентов c
Заказы RIGHT JOIN o ON o.customerid = c.customerid
ORDER BY orderid
Запрос возвращает все строки в таблице заказов и все совпадающие строки, найденные в клиентов стол.
На следующей диаграмме Венна показано, как работает правое внешнее соединение SQL:
SQL OUTER JOIN — полное внешнее соединение
Синтаксис полного внешнего соединения SQL следующий:
SELECT column1, column2...
ИЗ таблицы_A
ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ table_B ON join_condition
WHERE row_condition
Полное внешнее соединение SQL возвращает:
- все строки в левой таблице table_A.
- все строки в правой таблице table_B.
- и все соответствующие строки в обеих таблицах.
Некоторые системы управления базами данных не поддерживают синтаксис полного внешнего соединения SQL, например, MySQL. Поскольку полное внешнее соединение SQL возвращает результирующий набор, который является комбинированным результатом левого и правого соединения SQL.
SELECT столбец1, столбец2...
ИЗ таблицы_A
LEFT JOIN table_B ON join_condition
СОЮЗ
ВЫБЕРИТЕ столбец1, столбец2...
ИЗ таблицы_A
ПРАВОЕ СОЕДИНЕНИЕ table_B ON join_condition
SQL OUTER JOIN – пример полного внешнего соединения
Следующий запрос демонстрирует полное внешнее соединение SQL:
SELECT c.customerid, c.companyName, номер заказа ОТ клиентов c Заказы FULL OUTER JOIN o ON o.customerid = c.customerid ORDER BY orderid
На следующей диаграмме Венна показано, как работает полное внешнее соединение SQL:
В этом руководстве вы узнали о различных ВНЕШНИХ СОЕДИНЕНИЯХ SQL, включая левое соединение SQL, правое соединение SQL и полное внешнее соединение SQL.
sql — левое соединение с пунктом «Где»
Задавать вопрос
спросил
Изменено 1 год, 2 месяца назад
Просмотрено 573k раз
Мне нужно получить все настройки по умолчанию из таблицы настроек, а также получить настройку символа, если она существует для символа x.
Но этот запрос извлекает только те настройки, где символ = 1, а не настройки по умолчанию, если пользователь ничего не настроил.
ВЫБЕРИТЕ `настройки`.*, `character_settings`.`значение` ОТ (`настройки`) LEFT JOIN `character_settings` ON `character_settings`.`setting_id` = `settings`.`id` ГДЕ `character_settings`.`character_id` = '1'
Итак, мне нужно что-то вроде этого: массив
( '0' => массив('somekey' => 'имя ключа', 'значение' => 'значение'), '1' => массив('somekey2' => 'keyname2'), '2' => массив('somekey3' => 'keyname3') )
Где ключ 1 и 2 являются значениями по умолчанию, когда ключ 0 содержит значение по умолчанию с символьным значением.
- sql
- левое соединение
- где-пункт
Предложение where
отфильтровывает строки, в которых левое соединение
не удается. Переместите его в соединение:
SELECT `settings`.1*, `character_settings`.`value` ИЗ `настроек` ЛЕВОЕ СОЕДИНЕНИЕ `настройки персонажа` ON `character_settings`.`setting_id` = `settings`.`id` И `character_settings`.`character_id` = '1'
При выполнении ВНЕШНИХ СОЕДИНЕНИЙ (ANSI-89 или ANSI-92) место фильтрации имеет значение, поскольку критерии, указанные в пункте ON
, применяются до выполнения СОЕДИНЕНИЯ . Критерии для таблицы OUTER JOINed, представленные в предложении WHERE
, применяются после выполнения JOIN . Это может привести к очень разным наборам результатов. Для сравнения, для ВНУТРЕННИХ СОЕДИНЕНИЙ не имеет значения, указаны ли критерии в
или WHERE
— результат будет тот же.
ВЫБРАТЬ с.*, cs.`значение` ИЗ НАСТРОЕК LEFT JOIN CHARACTER_SETTINGS cs ON cs.setting_id = s.id И cs.character_id = 10
Если я правильно понимаю ваш вопрос, вам нужны записи из базы данных настроек, если они не имеют соединения с таблицей character_settings или если эта объединенная запись имеет character_id = 1.
Поэтому вы должны сделать
SELECT `settings`.*, `character_settings`.`value` ОТ (`настройки`) ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ `character_settings` ON `character_settings`.`setting_id` = `settings`.`id` ГДЕ `character_settings`.`character_id` = '1' ИЛИ `character_settings`.character_id равен NULL2
Вам может быть проще понять, используя простой подзапрос
SELECT `settings`.*, ( ВЫБЕРИТЕ `значение` ИЗ `character_settings` ГДЕ `character_settings`.`setting_id` = `настройки`.`id` И `character_settings`.`character_id` = '1') AS cv_value ИЗ `настроек`
Подзапрос может возвращать null, поэтому вам не нужно беспокоиться о JOIN/WHERE в основном запросе.
Иногда это работает на быстрее в MySQL, но сравните его с формой LEFT JOIN, чтобы увидеть, что лучше всего подходит для вас.
ВЫБРАТЬ с.*, c.значение ИЗ настроек с LEFT JOIN character_settings c ON c.setting_id = s.id AND c. character_id = '1'
Для этой проблемы, как и для многих других, связанных с нетривиальными левыми соединениями, такими как левое соединение для таблиц с внутренним соединением, я считаю удобным и несколько более читаемым разделить запрос с помощью с пунктом
. В вашем примере
с settings_for_char как ( выберите setting_id, значение из character_settings, где character_id = 1 ) выбирать настройки.*, settings_for_char.value от настройки оставил соединение settings_for_char на settings_for_char.setting_id = settings.id;
То, как я, наконец, понимаю, верхний ответ заключается в том, что осознается (следуя порядку выполнения SQL-запроса), что предложение WHERE применяется к объединенной таблице , тем самым отфильтровывая строки, которые не удовлетворяют условию WHERE из объединенного ( или вывод) таблица. Однако перемещение условия WHERE в предложение ON применяет его к отдельным таблицам 9.0003 до присоединения к .