自联结
就是一个表自己和自己联结,一般用来替代子查询
比如班上有 1 个学生数学考了 100 分,你不知道他是谁,你想知道他的其他学科的成绩
新手的写法
select student_id from score where type=’mathematics’ and score=100(假设结果为 27)
select * from score where student_id=27
或者
select * from score where student_id=(
select student_id from score where type=’mathematics’ and score=100
)
自联结的写法
select t1.* from score as t1,score as t2 where t1.student_id=t2.student_id and t2.type=’mathematics’ and t2.score=100
select t1.* from score as t1 inner join score as t2 on t1.student_id=t2.student_id where t2.type=’mathematics’ and t2.score=100
自然联结
无论何时对表进行联结,应该至少有一个列出现在不止一个表中(被联结的列)
标准的联结返回所有数据,甚至相同的列多次出现
自然联结排除多次出现,使每个列只返回一次
数据库通过自己的判断并使用表内所有相同的字段作为联结条件完成联结过程,不需要指定联结条件
一般的写法是第 1 个表用 * 指定字段,其他的表用明确的表字段指定
最好不要让数据库自动完成联结,不推荐使用
select * from t1 natural join t2(效果有点类似 inner join)
select * from t1 natural left join t2(效果有点类似 left join)
select * from t1 natural right join t2(效果有点类似 right join)
内部联结(又叫等值联结)
联结的 2 个表必须联结条件匹配才会得到数据
内部联结一般都是自然联结,很可能我们永远都不会用到不是自然联结的内部联结
select a.f1,b.f2 from a,b where a.f3=b.f4(不推荐这样的写法)
select a.f1,b.f2 from a inner join b on a.f3=b.f4(inner 关键字可以省略)
如果两个表是根据字段名一样的字段联结的,可以这样写
select t1.id,t2.name from t1 inner join t2 using(f)
外部联结
外部联结根据情况来确定是否包含那些在相关表中没有匹配的行
1. 左外部联结(又叫左联结)
左表的行一定会列出,右表如果没有匹配的行,那么列值就为 null
特别需要注意的是如果右表有多行和左表匹配,那么左表相同的行会出现多次
select a.f1,b.f2 from a left outer join b on a.f3=b.f4(outer 关键字可以省略)
2. 右外部联结(又叫右联结)
和左联结类似,只不过以右表为主表而已,左联结和右联结可以相互转化
select a.f1,b.f2 from a right outer join b on a.f3=b.f4(outer 关键字可以省略)
3. 全外部联结
返回左表和右表的所有行,不管有没有匹配,同时具有左联结和右联结的特性
select a.f1,b.f2 from a full outer join b on a.f3=b.f4(outer 关键字可以省略)
交叉联结
生成笛卡尔积,它不使用任何匹配或者选取条件,而是直接将一个数据源中的每个行与另一个数据源的每个行都一一匹配
select * from a cross join b
UNION 和 UNION ALL
UNION 不允许同一行 (每个字段都一样) 重复出现,而 UNION ALL 则没有这个限制
select A,B from u1
union all
select A,B from u2
关于联结的示意图