Вы можете поместить дополнительные условия в выражение левого внешнего соединения ON
. То, что вы хотите, это строка из carRims
, которая соответствует вашей строке rims
, и принадлежит автомобилю номер 9, верно?
SELECT
*
FROM
rims
LEFT OUTER JOIN
carRims
ON
carRims.rimId = rim.rimId
AND carRims.carId = 9
WHERE
carRims.carId IS NULL
Если есть другие carRims
для других автомобилей, они будут отфильтрованы дополнительным условием в предложении ON
.
Ваши вопросы о том, куда поставить условие, в JOIN
или в предложении WHERE
:
Для соединений external важно, куда вы поместите сравнение. Условие в предложении JOIN предназначено для проверки, соответствуют ли строки в одной таблице строкам в другой таблице. То, что мы делаем со строками из соответствующих таблиц после проверки соответствия, зависит от типа объединения.
Для внешнего объединения нам нужны строки из rims
, даже если в carRims
нет подходящей строки. Что если мы добавим условие carID = 9 в предложение WHERE
?
FROM rims r LEFT OUTER JOIN carRims c ON r.rimId = c.rimID
WHERE c.carID = 9
Вот что происходит: внешнее объединение возвращает все строки из rims
, причем строки из carRims
соответствуют rimID
, а включает строки с ложными значениями carID
. Только если нет автомобилей, соответствующих данному ободу, он использует NULL для c.*
столбцов.
Но тогда предложение WHERE
удаляет все строки, полученные в результате объединения, если только carID
не является значением 9. Это означает, что оно также устраняет, где carID
равно NULL, то есть оно удаляет строки для любого обода, не соответствующего ни одному из автомобилей. Следовательно, результат становится эквивалентным результату INNER JOIN
.
Таким образом, мы должны исключить строки из carRims
с неверным идентификатором carID, прежде чем строки будут объединены в rims
.
FROM rims r LEFT OUTER JOIN carRims c ON r.rimId = c.rimID AND c.carID = 9
Это условие того, какие строки из этой отдельной таблицы могут совпадать со строками в другой объединенной таблице.
Во многих книгах говорится, что вы можете свободно смешивать условия между предложением ON
и предложением WHERE
. Но это не так во всех случаях. Это работает для INNER JOIN
, потому что конечный результат в любом случае одинаков. Это также работает для условия, которое применяется только к левой таблице в левом соединении, например:
FROM rims r LEFT OUTER JOIN carRims c ON r.rimId = c.rimID AND r.make = 'ABC Rims'
FROM rims r LEFT OUTER JOIN carRims c ON r.rimId = c.rimID
WHERE r.make = 'ABC Rims'
Для условия на правой таблице в левом внешнем соединении, имеет значение , где вы ставите условие.
Еще один комментарий к тому, что вы сказали:
У меня есть ограничение: каждый тип обода должен быть соединен только один раз с каждым типом автомобиля. Поэтому все комбинации автомобильных дисков должны быть уникальными.
Итак, вы объявили UNIQUE
ограничение на carRims(carId,rimId)
?