Почему условия CROSS JOIN не работают в предложении ON, только в предложении WHERE?
Мне интересно, почему условное перекрестное соединение должно иметь условия, указанные в предложении WHERE, и почему оно не работает в предложении ON. Смотрите ссылку для скомпилированного примера: http://rextester.com/IKY8693
Бизнес-контекст: мне нужно сгенерировать список дат между начальной и конечной датой, чтобы заполнить пробелы, чтобы оставить соединение с третьей таблицей так, чтобы нули / нули возвращались в течение определенного месяца.
Как я это сделал: возьмем, к примеру, таблицу пользователей с датами начала и окончания ГГГГММ.
| user_id | start_yearmonth | end_yearmonth |
|---------|-----------------|---------------|
| u9876 | 201504 | 201610 |
| u5564 | 201602 | 201612 |
| u4435 | 201606 | NULL |
Таблица для перекрестного соединения - это таблица желаемых дат ГГГГММ.
| yearmonth |
|-----------|
| 201601 |
| 201602 |
| 201603 |
| 201604 |
| 201605 |
| 201606 |
| 201607 |
| 201608 |
| 201609 |
| 201610 |
| 201611 |
| 201612 |
| 201701 |
| 201702 |
Соединение CROSS с условиями в предложении where работает, но это не работает, когда условия находятся в предложении ON. Это почему?
SELECT
*
FROM
user_tbl
CROSS JOIN date_range
WHERE
user_tbl.start_yearmonth <= date_range.yearmonth
AND (user_tbl.end_yearmonth >= date_range.yearmonth
OR user_tbl.end_yearmonth IS NULL)
ORDER BY
user_tbl.user_id, date_range.yearmonth ;
1 ответ
CROSS JOIN - это оператор SQL для выполнения полного декартового произведения между двумя таблицами. Так как это декартово произведение, оно не допускает каких-либо условий во время операции, вы можете ограничить его результат только с помощью некоторой операции фильтрации (условие WHERE).
Операторы JOIN (INNER и OUTER JOIN, то есть) являются просто декартовым произведением вместе с оператором фильтрации, выраженным в ON-части оператора (и фактически в первоначальном синтаксисе SQL не было оператора JOIN, просто "запятая"). обозначение для обозначения продукта с условием соединения, выраженным всегда в части WHERE).
Примеры:
"старая" запись:
SELECT ...
FROM table1 t1, table2 t2
WHERE t1.attribute = t2.attribute
эквивалентно "современному" обозначению:
SELECT ...
FROM table1 t1 INNER JOIN table2 t2 ON t1.attribute = t2.attribute
в то время как для декартового произведения:
"старая" запись:
SELECT ...
FROM table1 t1, table2 t2
эквивалентно "современному" обозначению:
SELECT ...
FROM table1 t1 CROSS JOIN table2 t2
Другими словами, CROSS JOIN, который требует условия, на самом деле является своего рода INNER JOIN.