一、多表连接查询分类
首先先列举本篇用到的分类(内连接,外连接,交叉连接)和连接方法(如下):
A)内连接:join,inner join
B)外连接:left join,left outer join,right join,right outer join,union
C)交叉连接:cross join
实例:
两张假设有两张表格A和B,把表格当作一个集合,那么表格中的记录就是集合中的一个元素。
tableA:
tableB:
一. 内连接(只有一种场景)
语法:inner join 表 on 条件
或者join(inner 可以省略不写)
应用场景:这种场景下得到的是满足某一条件的A,B内部的数据;正因为得到的是内部共有数据,所以连接方式称为内连接。
sql:
select a.*, b.* from tablea a
join tableb b
on a.id = b.id
结果:id相等的A和B共有的数据
二、外连接(六种场景)
1,left join ......on....
应用场景:这种场景下得到的是A的所有数据,和满足某一条件的B的数据;如果B中没有数据的取null
sql:
select a.*, b.* from tablea a
left join tableb b
on a.id = b.id
结果:A的所有数据,和满足某一条件的B的数据;如果B中没有数据的取null
2, [left join + [where B.column is null]
应用场景:这种场景下得到的是A中的所有数据减去"与B满足同一条件 的数据",然后得到的A剩余数据;
sql:
select a.id aid,a.age,b.id bid,b.name from tablea a
left join tableb b
on a.id = b.id
Where b.id is null
结果:A中的所有数据减去"与B满足同一条件 的数据",然后得到的A剩余数据;
3,right join
应用场景:这种场景下得到的是B的所有数据,和满足某一条件的A的数据;
sql:
select a.id aid,a.age,b.id bid,b.name from tablea a
right join tableb b
on a.id = b.id
结果:得到的是B的所有数据,和满足某一条件的A的数据;
4,right join + [where A.column is null]
应用场景:这种场景下得到的是B中的所有数据减去 "与A满足同一条件 的数据“,然后得到的B剩余数据
sql:
select a.id aid,a.age,b.id bid,b.name from tablea a
right join tableb b
on a.id = b.id
where a.id is null
结果:
5,full join (mysql不支持,但是可以用 left join union right join代替)
应用场景:这种场景下得到的是满足某一条件的公共记录,和独有的记录
sql:
select a.id aid,a.age,b.id bid,b.name from tablea a
left join tableb b
on a.id = b.id
union
select a.id aid,a.age,b.id bid,b.name from tablea a
right join tableb b
on a.id = b.id
结果:union过后,重复的记录会合并(id为2,3,4的三条记录)
6.full join + is null(mysql不支持,但是可以用 (left join + is null) union (right join+isnull代替)
场景:这种场景下得到的是A,B中不满足某一条件的记录之和
sql:
select a.id aid,a.age,b.id bid,b.name from tablea a
left join tableb b
on a.id = b.id
where b.id is null
union
select a.id aid,a.age,b.id bid,b.name from tablea a
right join tableb b
on a.id = b.id
where a.id is null
结果:
注:上面共有其中七(2^3-1)种应用场景,还有一种是全空白,那就是什么都不查,七种情形包含了实际应用所有可能的场景
三、交叉连接 (cross join)
实际应用中还有这样一种情形,想得到A,B记录的排列组合,即笛卡儿积,这个就不好用集合和元素来表示了。需要用到cross join:
select a.id aid,a.age,b.id bid,b.name from tablea a
cross join tableb b
还可以为cross join指定条件 (where):
select a.id aid,a.age,b.id bid,b.name from tablea a
cross join tableb b
where a.id = b.id
结果如下:
注:这种情况下实际上实现了内连接的效果
三 注意事项
上面仍然存在遗漏,那就是mysql对sql语句的容错问题,即在sql语句不完全符合书写建议的情况,mysql会允许这种情况,尽可能地解释它:
3.1 一般cross join后面加上where条件,但是用cross join+on也是被解释为cross join+where;
3.2 一般内连接都需要加上on限定条件,如上面场景2.1;如果不加会被解释为交叉连接;
3.3 如果连接表格使用的是逗号,会被解释为交叉连接;
注:sql标准中还有union join和natural inner join,mysql不支持,而且本身也没有多大意义,其结果可以用上面的几种连接方式得到
原文参考:https://blog.csdn.net/jintao_ma/article/details/51260458