#mysql #sql #join #left-join
#mysql #sql #Присоединиться #левое соединение
Вопрос:
Следующие два запроса не возвращают один и тот же результат. Почему ?
Примечание: я нашел этот вопрос как головоломку Mysql, у меня нет больше данных по этому вопросу?
SELECT table1.*
FROM table1 LEFT JOIN table2
ON table2.table1_id = table1.id
AND table2.val < 5
SELECT table1.*
FROM table1 LEFT JOIN table2
ON table2.table1_id = table1.id
WHERE table2.val < 5
Ответ №1:
Левое внешнее соединение вернет строки (с нулевыми столбцами из table2, если они были выбраны), когда условие не выполняется, тогда как WHERE отфильтровывает их.
Комментарии:
1. @MarkByers В проекции не будет никаких нулевых строк (какие столбцы отображать), но запрошенный набор данных будет, и это имеет значение
2. @MarkByers Ну, в запросе № 1 будут нулевые значения из таблицы2.
3. @Adrian, в запросе 2 с помощью a
where
он превратил запрос во внутреннее соединение в соответствии с ответом Робина ниже. Вот почему набор результатов отличается.
Ответ №2:
Первый запрос вернет все строки из таблицы 1. Соединение по ЛЕВОМУ КРАЮ всегда возвращает все строки из левой таблицы, независимо от того, что вы пишете в условии соединения (однако оно может дублировать строки, если есть несколько совпадений, но поскольку вы объединяетесь по вызываемому полю id
, это, скорее всего, уникальный ключ, поэтому дубликатов не будет).
Второй запрос вернет только те строки из таблицы 1, в которых есть соответствующая строка в table2 val < 5
. На самом деле вы могли бы написать INNER JOIN
здесь, а LEFT JOIN
не потому, что строки, в которых происходит сбой соединения, в любом случае не будут в результирующем наборе из-за WHERE
предложения.
Ответ №3:
Первый запрос присоединяется только тогда, когда table2.val < 5
. Вторая фильтрует даже строки table1. Идентичный результат должен быть получен, если вместо этого вы используете INNER JOIN.
Ответ №4:
Пытаясь мыслить как «компилятор«, посмотрите на скобки…
SELECT table1.*
FROM table1
LEFT JOIN table2 ON (
table2.table1_id = table1.id
AND table2.val < 5
)
В этом примере выполняется ЛЕВОЕ ОБЪЕДИНЕНИЕ 2 таблиц, когда условие table2.table1_id = table1.id AND table2.val < 5
истинно.
SELECT table1.*
FROM table1
LEFT JOIN table2 ON ( table2.table1_id = table1.id )
WHERE (table2.val < 5)
В этом примере выполняется СОЕДИНЕНИЕ по ЛЕВОМУ КРАЮ, когда table2.table1_id = table1.id
применяется условие, а затем получаются строки результата table1 LEFT JOIN table2 ON ( table2.table1_id = table1.id )
, в КОТОРЫХ условие table2.val < 5
истинно