Если вы определяете ЛЕВОЕ СОЕДИНЕНИЕ, что
- для каждой строки из левой таблицы будет возвращаться соответствующая строка из правой таблицы, если она существует
- если строк с правой стороны не существует, он все равно будет возвращать строку из левой таблицы со всеми столбцами из правой таблицы, установленными в NULL
Теперь поймите, что существующее эквивалентно условию ON, оценивается как истинное, и все это имеет смысл.
Для строки, где t1.year равен 2010, выражение on оценивается как false (x AND 2010 = 2009 - false для всех строк, где t1.year = 2010), но поскольку это левое соединение, строка из левой таблицы будет все еще будет возвращено (согласно определению).
Поэтому такого рода условия можно записать только как условие, а не как условие соединения.
(в общем случае это не таблица, а выражение выбора)
EDIT:
Как интересно заметил Эрвин, условие where можно превратить в JOIN с помощью
select t1.*
from t1
left outer join t2
on t1.store = t2.store
or t1.year = '2009'
where t2.store is null
потому что:
t1.store t1.year t2.store t1.store=t2.store t1.year=2009 join(OR)
01 2009 02 false true true
02 2009 02 true true true
03 2009 02 false true true
01 2010 02 false false false
02 2010 02 true false true
03 2010 02 false false false
, поэтому только строки, в которых столбец соединения в приведенной выше таблице равен false , будут возвращать нули в полях t2. *.
Что я хотел сказать, так это то, что такого рода условие нельзя превратить в чистое соединение , потому что способ левого соединения работает (по-прежнему возвращает записи, даже если условие соединения ложно), что возможно при условия внутреннего соединения (могут быть превращены в чистые соединения и наоборот).
Относительно предложенного запроса - мой совет - не использовать его.
Запросы с OR, как правило, выполняются хуже, чем запросы с условиями AND (OR расширяет набор результатов; ANDs ограничивают). Это относится как к условиям присоединения, так и к условиям условия.
Ваш запрос будет работать хуже, чем запрос с t1.year = '2009' в условии where, потому что в более позднем случае будет возможно использовать индекс (если он существует), потому что, если вы присоединитесь, как вы, вы в основном искусственно объединяете записи из одной таблицы с записями из другой только для того, чтобы при условии вашего условия фильтровать только те записи, которые вам нужны.
Должно быть более эффективным получать только записи с t1, начиная с 2009 года (при условии, что существует годовой индекс и достаточно высокая селективность, что будет с условием WHERE).
Оба эти предложения относительно производительности могут и должны быть проверены путем проверки плана запроса.
Наконец, запрос немного неясен - не сразу очевидно, что в случае t1.year = '2009' объединение становится декартовым произведением (которое будет отфильтровано позже). Таким образом, если предположение о том, что простые LEFT JOIN
с where t1.year = 2009 AND t2.store is null
работают лучше И более читабельно, я бы не использовал этот запрос.