【问题标题】:Difference between ON and WHERE in subquery子查询中ON和WHERE的区别
【发布时间】:2016-06-17 17:22:31
【问题描述】:

我发现在 mysql 中使用 ON 和 WHERE 来过滤带有连接的子查询之间存在奇怪的差异。

这个查询运行良好:

SELECT * FROM cobrand co WHERE co.id IN (
    SELECT co2.id FROM cobrand co3 INNER JOIN cobrand co2 
    ON co2.id = co3.id + 1 
    WHERE co2.id = co.id
)

但是这个返回错误Unknown column 'co.id' in 'on clause':

SELECT * FROM cobrand co WHERE co.id IN (
    SELECT co2.id FROM cobrand co3 INNER JOIN cobrand co2 
    ON co2.id = co3.id + 1 
    AND co2.id = co.id
)

显然子查询的 ON 子句不能访问外部查询的别名,而 WHERE 子句可以。为什么会这样,任何人都可以指出文档中的哪个位置?

编辑:删除了涉及过早优化的不需要的背景信息。

【问题讨论】:

  • 请描述您需要查询做什么。我不相信子查询是必要的。
  • "(这很重要,因为在我的实际查询中,我在子查询中加入了更多表,并希望防止不需要的行被加入并产生更多不需要的行)" - 过早的优化。让优化器完成它的工作,然后分析执行计划,然后才考虑是否需要加快它。
  • @Amadan 你是对的......我不知道优化器会导致这两个查询执行相同......所以我不需要绕过这个限制,但是我仍想了解有关此语法错误的更多信息。我将编辑我的问题以反映这一点。
  • 这取决于您使用的连接类型。如果您使用的是 INNER JOIN,那么 ON & WHERE 将是相同的。如果连接是左/右,结果会有所不同

标签: mysql join syntax subquery


【解决方案1】:

以前,ON 子句可以引用名为 to 的表中的列 这是正确的。现在一个 ON 子句只能引用它的操作数。

例子:

CREATE TABLE t1 (i1 INT);
CREATE TABLE t2 (i2 INT);
CREATE TABLE t3 (i3 INT);
SELECT * FROM t1 JOIN t2 ON (i1 = i3) JOIN t3;

以前,SELECT 语句是合法的。现在声明失败 在“on 子句”错误中出现未知列“i3”,因为 i3 是 t3 中的列,它不是 ON 子句的操作数。该声明 应该改写如下:

SELECT * FROM t1 JOIN t2 JOIN t3 ON (i1 = i3);

-- MySQL docs, 13.2.9.2 JOIN Syntax

【讨论】:

  • 这里的关键部分是您只能使用作为 ON 子句操作数的列。
  • 如果有人好奇,“以前”这个词的意思是“在 MySQL 5.0.12 之前”。”
【解决方案2】:

where 子句适用于整个结果集。

on 子句仅适用于查询中的联接。

请参考以下链接

What's the difference between where clause and on clause when table left join?

In SQL / MySQL, what is the difference between "ON" and "WHERE" in a join statement?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 2013-06-20
    • 1970-01-01
    相关资源
    最近更新 更多