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
值的行将不会与 任何 其他行匹配。
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
值的行将不会与 任何 其他行匹配。