【问题标题】:sql self join without equal operator on columnsql self join 列上没有相等运算符
【发布时间】:2017-04-10 06:37:28
【问题描述】:

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

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

问题

给定一个 Weather 表,编写一个 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 |
+---------+------------+------------------+

例如,为上面的 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

【问题讨论】:

  • 这适用于哪个 RDBMS?无论您使用的是 MySQL、PostgreSQL、Oracle、SQL Server 还是 IBM DB2——甚至是其他东西,它通常都会产生影响。请为您的问题添加相关标签!
  • @marc_s,它适用于 MySQL 5.x。

标签: mysql join self-join


【解决方案1】:

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

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

联接只是匹配两组行的过程 - 您在联接的“左侧”有一个行源,在“右侧”有一个行源。在普通情况下,这些行源是表,但连接也可以将任何先前连接的结果连接为行源。

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

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

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

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

这很好。 TableID 最低的行将与表中的每个 其他行匹配。 ID 值最高的行将不会与 any 其他行匹配。

【讨论】:

  • 感谢 Damien_The_Unbeliever 的精彩回答,投票并标记为答案
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多