【问题标题】:JOIN (SELECT ... ) ue ON 1=1?加入(选择...) ue ON 1=1?
【发布时间】:2016-05-24 07:49:54
【问题描述】:

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

...
LEFT JOIN (SELECT MIN(modified) AS first_modified FROM user) ue
ON 1=1

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

【问题讨论】:

  • 它只是确保join 将返回匹配项——1=1true 相同。给定子查询,它只会返回一行——min(modified)。该值将合并到其他联接。几乎就像cross join,但只有一个值。

标签: sql postgresql join left-join amazon-redshift


【解决方案1】:

意图是一个无条件LEFT JOIN,它与CROSS JOIN不同在于左表表达式中的所有行即使在右表表达式中没有匹配项,也会返回 - 而 CROSS JOIN 从结果中删除此类行。 More on joins in the manual.

但是:

1=1 在 Postgres 和 all derivatives(包括 Amazon Redshift)中毫无意义。只需使用true。这可能是从另一个不正确支持 boolean 类型的 RDBMS 继承而来的。

... LEFT JOIN (SELECT  ...) ue ON true

再一次,LEFT JOIN 对于右侧带有 SELECT MIN(modified) FROM user 的特定子查询毫无意义,因为带有聚合函数 (min()) 且没有 GROUP BY 子句的 SELECT 始终只返回一行。这种情况(但不是其他可能发现没有行的情况)可以简化为:

... CROSS JOIN (SELECT MIN(modified) AS first_modified FROM user) ue

【讨论】:

    【解决方案2】:

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

    JOIN (LEFT, INNER, RIGHT, etc.) 语句通常需要一个“ON ...”条件。输入 1=1 就像是在说“1=1 始终为真,不要消除任何东西”。

    【讨论】:

    • 不完全是cross join,因为当右表不返回任何行时,cross join 也将不返回任何行,但left join on 1=1 将返回左表中所有空值的行作为右表.所以要小心重写。
    • join on trueleft join on true 不同,根据 stackoverflow.com/questions/21520048/…
    【解决方案3】:

    我相信它用于模拟笛卡尔连接。

    根据您的查询,修改最少的值(只有 1 个元素)将分配给左表的所有记录。

    PS:左连接在这里没有多大用处。还不如只使用内部连接

    【讨论】:

      【解决方案4】:

      我的回答是在 Erwin 的回答之上举例说明的。

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

      A1 -

      +-+
      |a|
      +-+
      |2|
      |1|
      |3|
      +-+
      

      B1-

      +----+
      |b   |
      +----+
      |a   |
      |b   |
      |c   |
      |NULL|
      +----+
      

      C1-

      +----+
      |c   |
      +----+
      

      在加入表 A1 和 B1 时,on 1=1 的行为与 CROSS JOIN 相同。

      select * from a1 left join b1 on 1=1;
      select * from a1 cross join b1;
      

      结果 -

      +-+----+
      |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   |
      +-+----+
      

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

      select * from a1 left join c1 on 1=1;
      

      结果 -

      +-+----+
      |a|c   |
      +-+----+
      |1|NULL|
      |3|NULL|
      |2|NULL|
      +-+----+
      

      对于交叉连接 -

      select * from a1 cross join c1;
      

      结果 -

      +-+-+
      |a|c|
      +-+-+
      

      【讨论】:

      • 太好了,谢谢你把例子写出来!
      猜你喜欢
      • 2015-12-07
      • 1970-01-01
      • 2011-03-03
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-08
      相关资源
      最近更新 更多