JOIN(SELECT ...)ue ON 1 = 1?

kee*_*kee 20 sql postgresql join left-join amazon-redshift

我正在Redshift中读取SQL查询,无法理解最后一部分:

...
LEFT JOIN (SELECT MIN(modified) AS first_modified FROM user) ue
ON 1=1
Run Code Online (Sandbox Code Playgroud)

ON 1=1这里的意思是什么?

Erw*_*ter 28

意图是无条件的 LEFT JOIN,这是不同的,从一个CROSS JOIN在返回从左侧表表达式中的所有行,即使在右表表达式没有匹配-而CROSS JOIN从结果滴这样的行.有关手册中的连接的更多信息.

然而:

1=1在Postgres和包括Amazon Redshift在内的所有衍生品都毫无意义.只是用true.这可能是从另一个不能boolean正确支持该类型的RDBMS中继承的.

... LEFT JOIN (SELECT  ...) ue ON true
Run Code Online (Sandbox Code Playgroud)

然后,LEFT JOIN对于SELECT MIN(modified) FROM user右边的这个特定子查询是没有意义的,因为SELECT带有聚合函数(min())和没有GROUP BY子句的a总是只返回一行.这种情况(但不是其他没有找到行的情况)可以简化为:

... CROSS JOIN (SELECT MIN(modified) AS first_modified FROM user) ue
Run Code Online (Sandbox Code Playgroud)


Pir*_*e X 14

我的回答是在埃尔文的回答之上用一个例子来说明的。

假设您有三个表 A1、B1 和 C1(空)

A1-

+-+
|a|
+-+
|2|
|1|
|3|
+-+
Run Code Online (Sandbox Code Playgroud)

B1-

+----+
|b   |
+----+
|a   |
|b   |
|c   |
|NULL|
+----+
Run Code Online (Sandbox Code Playgroud)

C1-

+----+
|c   |
+----+
Run Code Online (Sandbox Code Playgroud)

连接表 A1 和 B1 时,on 1=1行为与 相同CROSS JOIN

select * from a1 left join b1 on 1=1;
select * from a1 cross join b1;
Run Code Online (Sandbox Code Playgroud)

结果 -

+-+----+
|a|b   |
+-+----+
|1|NULL|
|1|a   |
|1|b   |
|1|c   |
|2|NULL|
|2|a   |
|2|b   |
|2|c   |
|3|NULL|
|3|a   |
|3|b   |
|3|c   |
+-+----+
Run Code Online (Sandbox Code Playgroud)

但是,当我们将 A1 与 C1 连接时,您会得到两个不同的结果

select * from a1 left join c1 on 1=1;
Run Code Online (Sandbox Code Playgroud)

结果 -

+-+----+
|a|c   |
+-+----+
|1|NULL|
|3|NULL|
|2|NULL|
+-+----+
Run Code Online (Sandbox Code Playgroud)

对于交叉连接 -

select * from a1 cross join c1;
Run Code Online (Sandbox Code Playgroud)

结果 -

+-+-+
|a|c|
+-+-+
Run Code Online (Sandbox Code Playgroud)

  • 太棒了,感谢您写出这个例子! (3认同)
  • 看例子就明白了 (2认同)

Bud*_*ssy 8

它只是做一个交叉连接,它选择第一个表中的所有行和第二个表中的所有行,并显示为笛卡尔积,即具有所有可能性.

JOIN(LEFT,INNER,RIGHT等)语句通常需要'ON ...'条件.输入1 = 1就像说"1 = 1总是如此,不要消除任何东西".

您可以将查询重写为

__PRE__

并获得相同的结果

  • 它不完全是`cross join`,因为当右表没有返回行时,`cross join`也将返回没有行,但是`left join on 1 = 1`将返回左表中的所有行,其中空值为右表.所以要小心重写. (7认同)
  • 这个答案是对的.检查欧文的答案. (4认同)