子查询是指超级查询的列,其中where和join之间的行为不同

时间:2017-09-29 03:56:25

标签: mysql

这是一件令我困惑的奇怪事情。它不是关于业务逻辑,而是关于SQL语法,或者至少我认为它是。

我创建了一个表格,并用以下数据填充:

create table test (
   col1 int,
   col2 int
);

insert into test values
(1, 1),
(2, 2),
(3, 3);

执行查询时

select *
from test t1
where exists(
    select 1
    from test t2
    join test t3
    on t2.col1 = t3.col1
    where t2.col2 = t1.col2
);

它产生以下结果(SQL fiddle):

| col1 | col2 |
|------|------|
|    1 |    1 |
|    2 |    2 |
|    3 |    3 |

这绝对是对的。

然后我将子查询中的where更改为and

select *
from test t1
where exists(
    select 1
    from test t2
    join test t3
    on t2.col1 = t3.col1
    and t2.col2 = t1.col2
);

这会产生以下错误(SQL fiddle):

  

'on clause'

中的未知列't1.col2'

我已经搜索了很长一段时间的原因,但无法弄明白。

我希望有人可以把我从这种混乱中带走。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

这不是语法错误。别名t1存在于"外部查询"中。只有WHERE子句或HAVING子句允许您引用外部查询(并且在执行此操作时,您将形成一个"相关的"子查询)。

JOIN无法引用外部查询(即该连接只能引用表别名t2和t3,因为它只能引用"内部"查询中的别名)

-- the "Outer query" is:
select *
from test t1

-- the "inner query" is:
select 1
from test t2
join test t3
on t2.col1 = t3.col1

你引入了一个"关联"在where子句中引用别名t1

select *
from test T1
where exists(
    select 1
    from test t2
    join test t3
    on t2.col1 = t3.col1
    where t2.col2 = T1.col2
);