转自:https://blog.csdn.net/u013468917/article/details/61933994
join过程可以这样理解:首先两个表做一个笛卡尔积,on后面的条件是对这个笛卡尔积做一个过滤形成一张临时表,如果没有where就直接返回结果,如果有where就对上一步的临时表再进行过滤。下面看实验:
1. 先执行inner join:
select * from person p inner join account a on p.id=a.id and p.id!=4 and a.id!=4;
select * from person p inner join account a on p.id=a.id where p.id!=4 and a.id!=4;
结果没有区别,前者是先求笛卡尔积然后按照on后面的条件进行过滤,后者是先用on后面的条件过滤,再用where的条件过滤。
2. 再看看左连接left join
select * from person p left join account a on p.id=a.id and p.id!=4 and a.id!=4;
这下看出来不对了,id为4的记录还在,这是由left join的特性决定的,使用left join时on后面的条件只对右表有效(可以看到右表的id=4的记录没了
select * from person p left join account a on p.id=a.id where p.id!=4 and a.id!=4;
where的过滤作用就出来了。。。
结果的关键原因就是 left join,right join,full join 的特殊性。
不管 on 上的条件是否为真都会返回 left 或 right 表中的记录,full 则具有 left 和 right 的特性的并集。
而 inner jion 没这个特殊性,则条件放在 on 中和 where 中,返回的结果集是相同的。