我想知道为什么条件交叉连接必须具有WHERE子句中指定的条件,以及为什么它不能在' ON'中工作。条款。 请参阅已编译示例的链接:http://rextester.com/IKY8693
业务上下文:我需要生成一个开始日期和结束日期之间的日期列表,以填补空白,以便在第三个表中保持连接,从而在特定月份返回零/空值。
我是如何做到的:让我们以一个用户表为例,其中包含YYYYMM的开始和结束日期。
| user_id | start_yearmonth | end_yearmonth |
|---------|-----------------|---------------|
| u9876 | 201504 | 201610 |
| u5564 | 201602 | 201612 |
| u4435 | 201606 | NULL |
要交叉连接的表是所需YYYYMM日期的表。
| yearmonth |
|-----------|
| 201601 |
| 201602 |
| 201603 |
| 201604 |
| 201605 |
| 201606 |
| 201607 |
| 201608 |
| 201609 |
| 201610 |
| 201611 |
| 201612 |
| 201701 |
| 201702 |
在where子句中有条件的CROSS JOIN有效,但当条件在' 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 ;
答案 0 :(得分:4)
CROSS JOIN是在两个表之间执行完整笛卡尔积的SQL运算符。由于它是笛卡尔积,它不允许在操作期间任何条件,您只能通过一些过滤操作(WHERE条件)来限制其结果。
JOIN(INNER和OUTER JOIN,即)运算符,只是笛卡尔积和过滤运算符一起表示在运算符的ON部分(实际上在SQL的原始语法中没有JOIN运算符,只是“逗号”符号表示始终在WHERE部分中表示连接条件的产品。
示例:
&#34;旧&#34;符号:
SELECT ...
FROM table1 t1, table2 t2
WHERE t1.attribute = t2.attribute
相当于&#34;现代&#34;符号:
SELECT ...
FROM table1 t1 INNER JOIN table2 t2 ON t1.attribute = t2.attribute
同时,对于笛卡尔积:
&#34;旧&#34;符号:
SELECT ...
FROM table1 t1, table2 t2
相当于&#34;现代&#34;符号:
SELECT ...
FROM table1 t1 CROSS JOIN table2 t2
换句话说,需要条件的CROSS JOIN实际上是某种INNER JOIN。