为什么CROSS JOIN条件在“ ON”子句中不起作用,仅在WHERE子句中起作用?

psr*_*psr 2 postgresql cross-join

我想知道为什么条件交叉联接必须具有WHERE子句中指定的条件,以及为什么它在'ON'子句中不起作用。请参阅编译示例的链接:http : //rextester.com/IKY8693

业务环境:我需要生成一个开始日期和结束日期之间的日期列表,以填补空白,以便与第三张表保持连接,以便在特定月份返回零/空值。

我是如何做到的:让我们以一个带有YYYYMM开始和结束日期的用户表为例。

| user_id | start_yearmonth | end_yearmonth |
|---------|-----------------|---------------|
| u9876   | 201504          | 201610        |
| u5564   | 201602          | 201612        |
| u4435   | 201606          | NULL          |
Run Code Online (Sandbox Code Playgroud)

要交叉连接的表是所需的YYYYMM日期的表。

| yearmonth |
|-----------|
| 201601    |
| 201602    |
| 201603    |
| 201604    |
| 201605    |
| 201606    |
| 201607    |
| 201608    |
| 201609    |
| 201610    |
| 201611    |
| 201612    |
| 201701    |
| 201702    |
Run Code Online (Sandbox Code Playgroud)

在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 ;
Run Code Online (Sandbox Code Playgroud)

Ren*_*nzo 9

CROSS JOIN是SQL操作符,用于在两个表之间执行完整的笛卡尔乘积。由于它是笛卡尔乘积,因此它在运算过程中不允许任何条件,您只能通过某些过滤运算(WHERE条件)来限制其结果。

JOIN(INNER和OUTER JOIN,即运算符)只是笛卡尔积,与在运算符的ON部分表示的过滤运算符一起(实际上,在SQL的原始语法中,没有JOIN运算符,只是“逗号”表示连接条件始终在WHERE部分中表示的产品的符号)。

例子:

“旧”表示法:

SELECT ...
FROM table1 t1, table2 t2
WHERE t1.attribute = t2.attribute
Run Code Online (Sandbox Code Playgroud)

等同于“现代”符号:

SELECT ...
FROM table1 t1 INNER JOIN table2 t2 ON t1.attribute = t2.attribute
Run Code Online (Sandbox Code Playgroud)

而对于笛卡尔积:

“旧”表示法:

SELECT ...
FROM table1 t1, table2 t2
Run Code Online (Sandbox Code Playgroud)

等同于“现代”符号:

SELECT ...
FROM table1 t1 CROSS JOIN table2 t2
Run Code Online (Sandbox Code Playgroud)

换句话说,需要条件的CROSS JOIN实际上是某种INNER JOIN。

  • 很好的答案,对此毫无保留,谢谢! (2认同)