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

时间:2017-04-10 06:37:29

标签: mysql join self-join

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

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

问题

给定一个Weather表,编写一个SQL查询来查找所有日期'与之前(昨天的)日期相比,温度较高的Ids。

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

例如,为上面的Weather表返回以下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

2 个答案:

答案 0 :(得分:2)

使用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

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

连接只是匹配两组行的过程 - 您在"左侧"上有一个行源。和#34;右边的行源#34;加入。在琐碎的情况下,这些行源是表,但是连接也可以将任何先前连接的结果作为行源连接。

理论上,在连接中,结果将是笛卡尔积 - 左边的每一行都与右边的每个行匹配。如果这是您想要的,您可以使用CROSS JOIN来表明这一点。

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

大多数常见类型的连接是等值连接,其中每侧的一个或多个列进行相等性比较。但这绝不是必需。它可以是任何有意义的谓词。例如。我经常使用的一种形式的连接,我将其描述为一个"三角形连接" (绝不是标准术语)每行与后来的每个行匹配:

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

这完全没问题。 IDTable最低的行将与表中的每个其他行匹配。 ID值最高的行将不会与任何其他行匹配。

答案 1 :(得分:1)

这称为“隐式联接” - 我建议您阅读SQL JOIN,例如https://en.wikipedia.org/wiki/Join_(SQL)

简而言之:数据库寻找拟合JOIN列而不要求您明确指定它们。