1

作为 SQL/MySQL 的后续,join 语句中的“ON”和“WHERE”有什么区别?SQL 连接:where 子句与 on 子句-如果将条件放置在 on-clause 与外部连接中的 where-clause 中,这确实很重要。

但是,当有多个外部连接时,将条件放在哪个子句中是否重要?

例如,这些会产生不同的结果吗?

select * from t1 left join t2 on t1.fid=t2.id and t2.col=val
                 left join t3 on t2.fid=t3.id;

与:

select * from t1 left join t2 on t1.fid=t2.id
                 left join t3 on t2.fid=t3.id and t2.col=val;
4

3 回答 3

1

他们绝对是不同的。

第一个查询将只有t2满足t2.col=val

第二个查询将包括所有t2行,并且仅t3在以下情况下列出t2.col=val

于 2014-12-28T20:26:19.183 回答
1

查询不等价。很容易构造一个反例:

create table t1 (id int not null, val int not null);
create table t2 (id int not null, val int not null);
create table t3 (id int not null, val int not null);
insert into t1 (id, val) values (1,1);
insert into t2 (id, val) values (1,1);
insert into t3 (id, val) values (1,1);

select * from t1 
left join t2 
    on t1.id = t2.id 
    and t2.val = 2 
left join t3 
    on t2.id = t3.id;
+----+-----+------+------+------+------+
| id | val | id   | val  | id   | val  |
+----+-----+------+------+------+------+
|  1 |   1 | NULL | NULL | NULL | NULL |
+----+-----+------+------+------+------+

select * from t1 
left join t2 
    on t1.id = t2.id 
left join t3 
    on t2.id = t3.id 
    and t2.val = 2;
+----+-----+------+------+------+------+
| id | val | id   | val  | id   | val  |
+----+-----+------+------+------+------+
|  1 |   1 |    1 |    1 | NULL | NULL |
+----+-----+------+------+------+------+
于 2014-12-28T21:48:20.140 回答
0

这是查询之一:

select *
from t1 left join
     t2
     on t1.fid = t2.id left join
     t3
     on t2.fid = t3.id and t2.col = val;

是的,结果不一样。如果您使用inner join它们,它们将是相同的,但会left join发生变化——因为该join子句不会对行进行任何过滤。

t1我认为最简单的解释是和之间的连接t2将包括来自的所有行t1以及来自的所有匹配行t2——即使是那些 where t2.col <> val。这些保留在结果集中,因为下一个left join不会将它们过滤掉。

事实上,t2.col = val第二on个子句中的条件并不影响结果集中哪些行。如果有匹配项,则来自t3第一个条件的行保持不变。如果没有匹配项,则来自的行t3仍在结果集中——但t3列将是NULL.

在这个版本中:

select *
from t1 left join
     t2
     on t1.fid = t2.id  and t2.col = val left join
     t3
     on t2.fid = t3.id;

第一个联接从 where 获取所有行,t1并且仅从t2where获取匹配行t2.col = val。然后第三个连接可以添加更多行。

注意:肯定有两个查询会返回相同结果的情况。但是,以下数据会产生不同的结果(假设 val = 0):

t1

fid
1

t2

fid   col
1     0
1     1

t3

id 
1

带有第二on个子句中条件的查询将返回:

1    1    0    1
1    1    1    NULL

第一on个子句中带有条件的查询将返回:

1    1    0    1
于 2014-12-28T21:44:01.953 回答