预备知识提要
SQL join 用于把来自两个或多个表的行结合起来。
下图展示了 LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法。
图片来自菜鸟教程
left join: 两个表join的时候,即使右边的表没有匹配中条件,左边表都会返回该行。 就是说不管怎么样 左边都会返回所有行,而右表只会返回匹配中的行,其余的都为null。
right join: 表join的时候,即使左边的表没有匹配中条件,右边表都会返回该行。 就是说不管怎么样 右边表都会返回所有行,而左表只会返回匹配中的行,其余的都为null。
full join: 表join的时候,只要其中一个表中存在匹配,则返回行。不满足匹配的都是null
inner join: 只有 表记录都匹配中了,才会返回行。 left join + right join。
join子句中 ON和WHERE的区别
先给结论:(对于left join来参考)
on 条件是在生成临时表时使用的条件,不管 on 中的条件是否为真,都会返回左边表中的记录。
where 条件是where 条件是在临时表生成好后,再对临时表进行过滤的条件。
left join
建两个表测试一下
person:
contact:
两条SQL:
SQL1: select p.name, c.tel from person p left join contact c on p.name = c.name where p.name = ‘jack’;
SQL2: select p.name, c.tel from person p left join contact c on p.name = c.name and p.name = ‘jack’;
SQL1结果:
SQL2结果:
可以看出 where条件会筛出 name = ‘jack’这一项 而on条件会保留其余两条记录
right join
使用同样的表
两条SQL:
SQL1: select p.name, c.tel from person p right join contact c on p.name = c.name where p.name = ‘jack’;
SQL2: select p.name, c.tel from person p right join contact c on p.name = c.name and p.name = ‘jack’;
SQL1结果:
SQL2结果:
同样可以看出, on条件 并不会过滤掉null的记录。
full join
使用同样的表(由于mysql不支持 full join, 所以我又去oracle建了两个相同的表)
两条SQL:
SQL1: select p.“name”, c.“tel” from “person” p FULL JOIN “contact” c on p.“name” = c.“name” and p.“name” =‘jack’
SQL2: select p.“name”, c.“tel” from “person” p FULL JOIN “contact” c on p.“name” = c.“name” where p.“name” =‘jack’
SQL1结果:
SQL2结果:
inner join
前三种是使用on 和where 结果不同的join方式,但inner join结果是相同的
SQL1: select p.name, c.tel from person p join contact c on p.name = c.name where p.name = ‘jack’;
SQL2: select p.name, c.tel from person p join contact c on p.name = c.name and p.name = ‘jack’;
SQL1结果:
SQL2结果:
这其实就是因为inner join没有其他那些join的特殊性,你必须要满足条件我才会放到临时表中。
回顾on 条件的含义:
on 条件是在生成临时表时使用的条件,它不管 on 中的条件是否为真,都会返回左边表中的记录。
所以说inner join 不会造成影响。