sql — левое соединение с пунктом «Где»
Задавать вопрос
спросил
Изменено 1 год, 2 месяца назад
Просмотрено 573k раз
Мне нужно получить все настройки по умолчанию из таблицы настроек, а также получить настройку символа, если она существует для символа x.
Но этот запрос извлекает только те настройки, где символ = 1, а не настройки по умолчанию, если пользователь ничего не настроил.
ВЫБЕРИТЕ `настройки`.*, `настройки_символа`.`значение` ОТ (`настройки`) 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`.*, `character_settings`.`value` ИЗ `настроек` ЛЕВОЕ СОЕДИНЕНИЕ `настройки персонажа` ON `character_settings`.`setting_id` = `settings`.`id` И `character_settings`.`character_id` = '1'1
При выполнении ВНЕШНИХ СОЕДИНЕНИЙ (ANSI-89 или ANSI-92) место фильтрации имеет значение, поскольку критерии, указанные в пункте ON
, применяются до выполнения СОЕДИНЕНИЯ
WHERE
, применяются после выполнения JOIN . Это может привести к очень разным наборам результатов. Для сравнения, для ВНУТРЕННИХ СОЕДИНЕНИЙ не имеет значения, указаны ли критерии в ON
или 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 равен NULL
Вам может быть проще понять, используя простой подзапрос
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 из объединенного ( или вывод) таблица.
Результат правильный на основе инструкции SQL. Левое соединение возвращает все значения из правой таблицы и только совпадающие значения из левой таблицы.
Столбцы ID и NAME взяты из правой таблицы, поэтому возвращаются.
Счет берется из левой таблицы, и возвращается 30, так как это значение относится к имени «Поток». Другие имена имеют значение NULL, поскольку они не относятся к имени «Поток».
Следующий результат вернет ожидаемый результат:
SELECT a.*, b.Score ОТ @Table1 а ЛЕВОЕ СОЕДИНЕНИЕ @Table2 b ON a.ID = b.T1_ID ГДЕ 1=1 И a.Name = 'Поток'
SQL применяет фильтр к правой таблице.
1SQL LEFT JOIN — SQL
На языке SQL команда LEFT JOIN (с добавлением LEFT OUTER JOIN) является типом соединения для 2 таблиц. Cela permet de lister tous les résultats de la table de gauche (слева = gauche) même s’il n’y a pas de cosplay dans la deuxième table.
Неверное соединение (LEFT JOINT)
Синтаксис
Список регистрации регистрации таблицы 1, мем не имеет соответствия с таблицей 2, он удобен для запроса SQL с использованием удобного синтаксиса .
ВЫБОР * ИЗ таблицы1 LEFT JOIN table2 ON table1.id = table2.fk_id
La requête peux aussi s’écrire de la façon suivante:
SELECT * ИЗ таблицы1 LEFT OUTER JOIN table2 ON table1.id = table2.fk_id
Cette requête est particulièrement intéressante pour récupérer les informations de table1 tout en recupérant les données associées, meme s’il n’y pas de переписка a vec таблица2 . A savoir, s’il n’y a pas de cosplay les colonnes de таблица2 четких слов NULL.
Пример
Imaginons содержит приложения, предназначенные для пользователей, и команды, предназначенные для пользователей. La base de données de Cette application contient une table pour les utilisateurs et sauvegarde leurs achats dans une seconde table. На 2 столах нет опорных столбов
Таблица utilisateur :
id | prenom | nom | ville | |
---|---|---|---|---|
1 | Эме | Марешаль | [email protected] | Париж |
2 | Эсме | Лефорт | [email protected] | Лион |
3 | Морской | Прево 9 0162 | [email protected] | Лилль |
4 | Люк | Роллан | [email protected] | Марсель |
90 047 Команда таблицы:
utilisateur_id | date_achat | num_facture | prix_total |
---|---|---|---|
1 | 23. 01.2013 | A00103 | 203.14 |
1 | 1.02.2013 4 | A00104 | 124,00 |
2 | 17.02.2013 | A00105 | 149,45 |
2 | 9016 1 21.02.2013A00106 | 235.35 | |
5 | 02.03.2013 | A00107 | 47.58 |
Pour lister tous les utilisateurs avec leurs commandes et afficher également les utilisateurs qui n’ont pas effectuées d’achats, il est d’ используйте соответствующий запрос:
SELECT * ОТ утилизатора LEFT JOIN commande ON utilisateur.id = commande.utilisateur_id
Результаты:
id | prenom | nom | num_f acture | prix_total | |
---|---|---|---|---|---|
1 | Эме | Марешаль | 23.01.2013 | 9016 1 А00103203.14 | |
1 | Эме | Марешаль | 14. 02.2013 | A00104 9016 2 | 124,00 |
2 | Эсме | Лефорт | 17.02.2013 | A00105 | 149,45 |
2 | 9016 1 EsméeLefort | 21.02.2013 | A00106 | 235,35 | |
3 | Морской | Prevost | NULL | NULL | NULL |
4 | Luc | Rolland | NULL | NULL | NULL |
Les dernières lignes montrent des utilisateurs qui n’ont effectuée aucune commande. La ligne retourne la valeur NULL pour les Colnes, касающийся les achats qu’ils n’ont pas effectués.
Фильтр по стоимости NULL
Внимание, стоимость NULL не является цепочкой характеристик. Pour filtrer sur ces caractères il faut utiliser la commande IS NULL. Par example, pour lister les utilisateurs qui n’ont pas effectués d’achats il est возможно d’utiliser la requête suivante.