sql — Left Join With Where Пункт
Мне нужно получить все настройки по умолчанию из таблицы настроек, а также получить настройку символа, если она существует для символа 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 , применяются до выполнения JOIN . Критерии для таблицы 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`.`значение` ОТ (`настройки`) ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ `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 применяет его к отдельным таблицам до объединения . Это позволяет левому объединению сохранять строки из левой таблицы, даже если некоторые записи столбцов этих строк (записи из правых таблиц) не удовлетворяют условию WHERE.
1
Результат правильный на основе оператора SQL. Левое соединение возвращает все значения из правой таблицы и только совпадающие значения из левой таблицы.
Столбцы ID и NAME взяты из правой таблицы, поэтому возвращаются.
Оценка берется из левой таблицы, и возвращается 30, так как это значение относится к имени «Поток». Другие имена имеют значение NULL, поскольку они не относятся к имени «Поток».
Следующий результат вернет ожидаемый результат:
ВЫБЕРИТЕ a.*, b.Оценка
ОТ @Table1 а
ЛЕВОЕ СОЕДИНЕНИЕ @Table2 b
ON a.ID = b.T1_ID
ГДЕ 1=1
И a.Name = 'Поток'
SQL применяет фильтр к правой таблице.
1
LEFT JOIN с использованием SQL (включая примеры) — Data to Fish
12 февраля 2022 г.
Вы можете использовать LEFT JOIN, чтобы получить все записи из левой таблицы и записи из правой таблицы, где есть соответствует (если совпадения нет, вы получите NULL под выбранными полями из правой таблицы):
SELECT ТБ1.*, ТБ2.* ОТ left_table_name tb1 LEFT JOIN right_table_name tb2 ON tb1.id = tb2.id
Давайте посмотрим, как применить левое соединение, рассмотрев несколько примеров.
Применение левого соединения между двумя таблицами с помощью SQL
В следующем примере вы увидите, как применить левое соединение между:
- Левая таблица с именем продукты ; и
- Правая таблица называется цены
Вы можете создать таблицу « products », используя следующий запрос:
CREATE TABLE products ( product_id int первичный ключ, product_name nvarchar(50) )
А затем вставьте в таблицу 5 записей:
INSERT INTO products (product_id, product_name) ЦЕННОСТИ (1, «Ноутбук»), (2, «Планшет»), (3, «Монитор»), (4, «Принтер»), (5, «Клавиатура»)
Затем вы можете создать таблицу « цены », используя следующий синтаксис:
СОЗДАТЬ ТАБЛИЦУ цены ( product_id int первичный ключ, product_price целое )
Затем вставьте в таблицу 5 записей:
ВСТАВИТЬ В цены (product_id, product_price) ЦЕННОСТИ (1, 1200), (2, 300), (3, 500), (4, 150), (5, 80)
Наконец, вы можете применить ЛЕВОЕ СОЕДИНЕНИЕ, используя приведенный ниже запрос.
Обратите внимание, что 9Поле 0037 product_id (существующее в обеих таблицах) будет использоваться для связывания таблиц вместе:
SELECT tb_1.*, tb_2.* ИЗ продуктов tb_1 LEFT JOIN цены tb_2 ON tb_1.product_id = tb_2.product_id
Зеленым цветом показаны все записи и поля из таблицы products («левая» таблица), а желтым — все записи и поля из таблицы Prices
(«правая» таблица). ” таблица):| product_id | имя_продукта | product_id | цена_продукта |
| 1 | Ноутбук | 1 | 1200 |
| 2 | Планшет | 2 | 300 |
| 3 | Монитор | 3 | 500 |
| 4 | Принтер | 4 | 150 |
| 5 | Клавиатура | 5 | 80 |
Выбор подмножества полей
Иногда может потребоваться выбрать подмножество полей из объединенных таблиц.
Например, выберем:
- Поля product_id и product_name из таблицы «products»; и
- Поле
product_price из таблицы «Цены»
Вот запрос:
ВЫБЕРИТЕ tb_1.product_id, tb_1.имя_продукта, tb_2.product_price ИЗ продуктов tb_1 LEFT JOIN цены tb_2 ON tb_1.product_id = tb_2.product_id
Теперь вы увидите только выбранные поля из таблиц:
| product_id | имя_продукта | цена_продукта |
| 1 | Ноутбук | 1200 |
| 2 | Планшет | 300 |
| 3 | Монитор | 500 |
| 4 | Принтер | 150 |
| 5 | Клавиатура | 80 |
Применение левого соединения к нескольким таблицам с использованием SQL
Теперь создадим третью таблицу с именем « brand »:
CREATE TABLE brand ( product_id int первичный ключ, product_brand nvarchar(50) )
А затем вставить 5 записей:
ВСТАВИТЬ В бренды (product_id, product_brand) ЦЕННОСТИ (1, 'ДД'), (2, 'ЧЧ'), (3, 'ММ'), (4, «ПП»), (5, 'RR')
Предположим, вы хотите выполнить левое соединение нескольких таблиц (в нашем примере это 3 таблицы: продукты, цены и бренды).
В этом случае вы можете выполнить следующий запрос:
SELECT tb_1.product_id, tb_1.имя_продукта, tb_2.product_price, tb_3.product_brand ИЗ продуктов tb_1 LEFT JOIN цены tb_2 ON tb_1.product_id = tb_2.product_id ЛЕВОЕ СОЕДИНЕНИЕ брендов tb_3 ON tb_1.product_id = tb_3.product_id
Как видите, первое и второе поля были выбраны из products table (зеленый), третье поле выбрано из таблицы Prices (желтый), а четвертое поле выбрано из таблицы brands (оранжевый):
| product_id | имя_продукта | | product_brand |
| 1 | Ноутбук | 1200 | ДД |
| 2 | Таблетка | 300 | ЧЧ |
| 3 | Монитор | 500 | ММ |
| 4 | Принтер | 150 | ПП |
| 5 | Клавиатура | 80 | РУБ |
Другой способ написать вышеуказанный запрос:
SELECT tb_1.product_id, tb_1.имя_продукта, tb_2.product_price, tb_3.product_brand ОТ ( ВЫБИРАТЬ * ИЗ продуктов ) тб_1 ЛЕВОЕ СОЕДИНЕНИЕ (( ВЫБИРАТЬ * ОТ цены )) tb_2 ON tb_1.product_id = tb_2.product_id ЛЕВОЕ СОЕДИНЕНИЕ ((( ВЫБИРАТЬ * ОТ брендов ))) tb_3 ПО tb_1.product_id = tb_3.product_id
Вы получите те же результаты, что и раньше:
| product_id | имя_продукта | цена_продукта | product_brand |
| 1 | Ноутбук | 1200 | ДД |
| 2 | Планшет | 300 | ЧЧ |
| 3 | Монитор | 500 | ММ |
| 4 | Принтер | 150 | ПП |
| 5 | Клавиатура | 80 | РУБ |
И еще один способ написать вышеуказанный запрос:
SELECT микс.

setting_id = s.id
И cs.character_id = 1
product_id,
tb_1.имя_продукта,
tb_2.product_price,
tb_3.product_brand
ОТ
(
ВЫБИРАТЬ
*
ИЗ продуктов
) тб_1
ЛЕВОЕ СОЕДИНЕНИЕ
((
ВЫБИРАТЬ
*
ОТ цены
)) tb_2 ON tb_1.product_id = tb_2.product_id
ЛЕВОЕ СОЕДИНЕНИЕ
(((
ВЫБИРАТЬ
*
ОТ брендов
))) tb_3 ПО tb_1.product_id = tb_3.product_id
