Зачем LEFT JOIN на поле, чтобы затем отфильтровать его в предложении WHERE? - PullRequest
0 голосов
/ 19 ноября 2018

Запрос

SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN Table2 ON Table1.ID = Table2.ID
WHERE Table2.ID IS NULL

Задача

  • Трудно понять, почему кто-то оставил присоединиться к ID и затем установите его в NULL в предложении where?
  • Я что-то здесь упускаю? Есть ли какое-то значение для этого?
  • Можем ли мы просто опустить Table2 в целом? Как вообще не присоединяться?

Любая помощь будет высоко ценится.

Ответы [ 4 ]

0 голосов
/ 19 ноября 2018

Я думаю, что у вас должен быть псевдоним для вашей таблицы и указать, из какой таблицы идет каждый столбец.

Если предположить, что имя взято из первой таблицы, а телефон является второй таблицей формы, а идентификатор является общим для обоих, тоЛевое объединение, упомянутое выше, может помочь получить всех пользователей, у которых нет телефонных номеров.

Таблица 1
Идентификационное имя
1 Джон Смит
2 Джейн Доу

Таблица 2
Идентификатор телефона
2 071 555 0863

Соединение влево без предложения where
Идентификационное имя Телефон
1 John Smith NULL
2 Jane Doe 071 555 0863

Left Присоединитесь к предложению where
ID Имя Телефон
1 John Smith NULL

0 голосов
/ 19 ноября 2018

Это один из способов реализации операции antijoin для реляционной базы данных, называемой anti semi join в терминологии сервера sql.По сути, это «перенести строки из одной таблицы, которых нет в другой таблице».

Я не могу думать об этом следующим образом:

select cols from t1 left join t2 on t1.key=t2.key where t2.key is null

select cols from t1 where key not in (select key from t2)

select cols from t1 where not exists (select 1 from t2 where t1.key=t2.key)

и даже

select * from t1 where key in (select key from t1 except select key from t2)

Существуют некоторые различия между этими методами (в частности, опасность нулевой обработки вслучай not in), но обычно они делают то же самое.


Для решения ваших вопросов:

Трудно понять, почему кто-то оставил присоединиться кID и затем установите его в NULL в предложении where?

Как уже упоминалось, для исключения результатов из t1, которые присутствуют в t2

Можем ли мы просто опуститьТаблица2 в целом?Как вообще не объединяться?

Если вы не используете объединение (или любую из его альтернатив эквивланта), вы получите больше результатов, так как строки в таблице1 имеют одинаковый идентификатор свсе строки в table2 также будут возвращены.

0 голосов
/ 19 ноября 2018

Если столбец условия соединения имеет нулевое значение, а именно ID, то, по моему мнению, это плохой дизайн базы данных.

Согласно вашему запросу ниже. Вот возможный сценарий, почему пункт где имеет смысл

  1. Я предполагаю, что ваше имя и номер телефона взяты из таблицы 2, а затем вы пытаетесь найти имя и номер телефона, чей идентификатор является нулевым.

  2. Если имя и номер телефона взяты из таблицы 1, а в таблице 2 просто присоединение идентификатора и ничего из таблицы 2 не выбрано, то где пункт - общий объем отходов.

    ВЫБРАТЬ Я БЫ, Название, Телефон ОТ Таблица 1 ЛЕВОЕ СОЕДИНЕНИЕ Таблица 2 НА Table1.ID = Table2.ID ГДЕ Table2.ID НЕДЕЙСТВИТЕЛЕН

По сути, в приведенном выше общем бизнес-сценарии разработчики помещают критерии фильтра условия where в левое объединение, когда любое значение, поступающее с правой стороны, имеет не релевантные данные и не обязательно должно быть частью набора данных, а затем отфильтровывает его.

0 голосов
/ 19 ноября 2018

Запрос в вашем вопросе в основном эквивалентен следующему запросу:

SELECT ID, Name, Phone 
FROM Table1 
WHERE NOT EXISTS
(
    SELECT 1
    FROM  Table2 
    WHERE Table1.ID = Table2.ID
)

То есть он выбирает все записи в Таблице 1, у которых нет коррелированных записей в Таблице 2.

План выполнения для обоих запросов, скорее всего, будет одинаковым (лично я никогда не видел случая, чтобы они производили другой план выполнения, но я не исключаю этого), поэтому оба запроса должны быть одинаково эффективными, иВам решать, будет ли левое соединение или существующий синтаксис более читабельным.

...