sql 列上没有相等运算符的自连接

sql self join without equal operator on column

Post 问题和 SQL 有效的解决方案。我的困惑是,当我过去进行自连接时,要连接的列中总是有一些相等的值(等于运算符),但在下面的示例中,自连接似乎可以在不使用等于运算符的情况下工作?在我下面的示例中,使用减号运算符和 >,没有等于运算符来指定用于连接的列。

想知道如果没有相等运算符,底层自连接在我的示例中是如何工作的?

问题,

给定天气 table,编写一个 SQL 查询以查找与之前(昨天)日期相比温度更高的所有日期的 ID。

+---------+------------+------------------+
| Id(INT) | Date(DATE) | Temperature(INT) |
+---------+------------+------------------+
|       1 | 2015-01-01 |               10 |
|       2 | 2015-01-02 |               25 |
|       3 | 2015-01-03 |               20 |
|       4 | 2015-01-04 |               30 |
+---------+------------+------------------+

例如,return 上述天气 table 的以下 ID:

+----+
| Id |
+----+
|  2 |
|  4 |
+----+

SQL解决方案,

select W1.Id
from Weather W1, Weather W2
where TO_DAYS(W1.Date)-TO_DAYS(W2.Date) = 1 and W1.Temperature > W2.Temperature

这叫做 "implicit join" - 我建议您阅读 SQL JOIN,例如 https://en.wikipedia.org/wiki/Join_(SQL)

简而言之:数据库会查找合适的 JOIN 列,而不需要您明确指定它们。

使用 ANSI 连接编写它,因为它们是 SQL:

的标准部分
select W1.Id
from Weather W1
        inner join
     Weather W2
        on TO_DAYS(W1.Date)-TO_DAYS(W2.Date) = 1 and
           W1.Temperature > W2.Temperature

(应该产生相同的结果集)

连接只是匹配两组行的过程 - 您在连接的 "left" 上有一个行源,在连接的 "right" 上有一个行源。在一般情况下,这些行源是 tables,但连接也可以连接任何先前连接的结果作为行源。

理论上,在联接中,结果将是笛卡尔积 - 左侧的每一行都将与右侧的 每个 行匹配。如果这是您想要的,您可以用 CROSS JOIN.

表示

但是,通常我们希望限制 连接的结果小于行的笛卡尔积。我们通过编写 ON 子句(或在您示例中的 WHERE 子句中使用旧式逗号连接)来表达这些限制。

常见 的联接类型是等值联接,其中比较每一侧的一个或多个列是否相等。但这绝不是必需的。它可以是任何有意义的谓词。例如。我半定期使用的一种连接形式我描述为 "triangle join"(绝不是标准术语),其中每一行都与后面的 every 行匹配:

SELECT
    *
FROM
    Table t1
        left join
    Table t2
        on
           t1.ID < t2.ID

这很好。 Table 中具有最低 ID 的行将与 table 中的其他 每隔 行匹配。具有最高 ID 值的行将不会与 任何 其他行匹配。