Left join on: Секция JOIN | ClickHouse Docs

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
  • левое соединение
  • где-пункт
0

Предложение where отфильтровывает строки, где левое соединение не удалось. Переместите его в соединение:

 SELECT `settings`.*, `character_settings`.`value`
ИЗ `настроек`
ЛЕВОЕ СОЕДИНЕНИЕ
       `настройки персонажа`
ON `character_settings`.`setting_id` = `settings`.`id`
        И `character_settings`.`character_id` = '1'
 
1

При выполнении ВНЕШНИХ СОЕДИНЕНИЙ (ANSI-89 или ANSI-92) место фильтрации имеет значение, поскольку критерии, указанные в пункте ON , применяются до выполнения СОЕДИНЕНИЯ

. Критерии для таблицы OUTER JOINed, указанные в предложении WHERE , применяются после выполнения JOIN . Это может привести к очень разным наборам результатов. Для сравнения, для ВНУТРЕННИХ СОЕДИНЕНИЙ не имеет значения, указаны ли критерии в ON или WHERE пунктов — результат будет тот же.

 ВЫБРАТЬ с.*,
          cs.`значение`
     ИЗ НАСТРОЕК
LEFT JOIN CHARACTER_SETTINGS cs ON cs.setting_id = s.id
                               И cs.character_id = 1
 
0

Если я правильно понял ваш вопрос, вам нужны записи из базы данных настроек, если они не имеют соединения с таблицей 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
 
2

Вам может быть проще понять, используя простой подзапрос

 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.0047 до вступления в . Это позволяет левому объединению сохранять строки из левой таблицы, даже если некоторые записи столбцов этих строк (записи из правых таблиц) не удовлетворяют условию WHERE.

1

Результат правильный на основе инструкции SQL. Левое соединение возвращает все значения из правой таблицы и только совпадающие значения из левой таблицы.

Столбцы ID и NAME взяты из правой таблицы, поэтому возвращаются.

Счет берется из левой таблицы, и возвращается 30, так как это значение относится к имени «Поток». Другие имена имеют значение NULL, поскольку они не относятся к имени «Поток».

Следующий результат вернет ожидаемый результат:

 SELECT a.*, b.Score
ОТ @Table1 а
    ЛЕВОЕ СОЕДИНЕНИЕ @Table2 b
       ON a.ID = b.T1_ID
ГДЕ 1=1
И a.Name = 'Поток'
 

SQL применяет фильтр к правой таблице.

1

SQL 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 де-ла-таблица команд. Cela permet d’associer une commande à un utilisateur.

Таблица utilisateur :

id prenom nom email ville
1 Эме Марешаль [email protected] Париж
2 Эсме Лефорт [email protected] Лион
3 Морской Прево 9 0162 [email protected] Лилль
4 Люк Роллан [email protected] Марсель

90 047 Команда таблицы:

9 0159 9016 1 21.02.2013
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 A00106 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 

Результаты:

9016 1 А00103 9016 1 Esmée
id prenom nom
date_achat
num_f acture prix_total
1 Эме Марешаль 23.01.2013 203.14
1 Эме Марешаль 14. 02.2013 A00104 9016 2 124,00
2 Эсме Лефорт 17.02.2013 A00105 149,45
2 Lefort 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.

Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *