Postgresql 为什么交叉连接条件在“ON”子句中不起作用,而只在WHERE子句中起作用?
我想知道为什么条件交叉连接必须在WHERE子句中指定条件,为什么它在“ON”子句中不起作用。有关编译示例,请参见链接: 业务上下文:我需要生成一个开始日期和结束日期之间的日期列表,以填补空白,以便与第三个表左键联接,从而为特定月份返回零/空 我是如何做到这一点的:让我们以一个用户表为例,其中包含YYYYMM开始和结束日期Postgresql 为什么交叉连接条件在“ON”子句中不起作用,而只在WHERE子句中起作用?,postgresql,cross-join,Postgresql,Cross Join,我想知道为什么条件交叉连接必须在WHERE子句中指定条件,为什么它在“ON”子句中不起作用。有关编译示例,请参见链接: 业务上下文:我需要生成一个开始日期和结束日期之间的日期列表,以填补空白,以便与第三个表左键联接,从而为特定月份返回零/空 我是如何做到这一点的:让我们以一个用户表为例,其中包含YYYYMM开始和结束日期 | user_id | start_yearmonth | end_yearmonth | |---------|-----------------|-------------
| 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子句中包含条件的交叉联接有效,但当条件位于“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 ;
交叉联接是在两个表之间执行完全笛卡尔乘积的SQL运算符。由于它是笛卡尔积,因此在操作过程中不允许任何条件,您只能通过一些过滤操作限制其结果,其中包含条件 联接内部联接和外部联接,即运算符,只是笛卡尔积和在运算符的ON部分表示的过滤运算符,事实上在SQL的原始语法中没有联接运算符,只是用“逗号”符号表示联接条件始终在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
相当于现代符号:
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
而对于笛卡尔积:
旧符号:
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
相当于现代符号:
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
换句话说,需要条件的交叉连接实际上是某种内部连接。什么意思?交叉联接不支持打开。你可以把它看作是两个集合的笛卡尔积,on没有意义。我想我的问题很清楚——我特别想问为什么交叉连接不支持on“ON”用于在两个表之间创建条件,不是吗?是的,并且不使用交叉联接创建任何条件。其他类型的联接必须满足条件。就这么简单。如果您希望在交叉联接上添加条件,那么您必须在交叉联接语句之外添加条件。这不是交叉联接。它是一个笛卡尔积与一组日期范围记录(与用户记录匹配)的内部联接。说交叉联接的唯一原因是,如果您想要所有行的完全笛卡尔积,那么您不必指定ON子句。就我个人而言,我想说交叉左连接,但那是另一个故事。我仍然不知道为什么有人对这个问题投了反对票。非常好的回答,没有任何空气,谢谢!在标准SQL中,必须使用带内部联接的ON。