在未使用表的自身查询时,并没有发现连接查询的问题,可能也就想一想,合理了也就没有再过问。但是在学习慕课网课程时,使用自身连接查询,突然感觉不明白连接查询到底是什么情况了。以前读过萨师煊的《数据库系统概论》,对于当时的SQL语句的运算还有点印象,自己又实验了一下,感觉应该是懂的了连接查询的一部分原理。
现有数据表tdb_goods_types,是一种无限级分类表,存储的是电器种类分类:
parent_id表示该分类的上一级分类的id。
当使用左连接时,系统根据左表的记录去扫描右表的记录。
左连接:
select t.type_name as T_typename,s.type_name as S_typename from tdb_goods_types as t
left join tdb_goods_types as s
on t.parent_id = s.type_id;
连接条件是t.parent_id = s.type_id,所以从左表第一条记录开始,parent_id=0,在右表中从第一条记录开始,判断是否符合parent_id = type_id,一直扫描到最后一条记录也没有匹配到符合条件的记录,因为左连接是不会丢失左表的数据的,所以将左表中的此条记录存入到连接结果集中,并生成一个为NULL的右表列。
到左表的第二条记录,系统从右表第一条记录开始,仍然如上扫描,未找到匹配记录,将左表中的第二条记录存入到结果表中,并生成一个为NULL的右表列。
到左表的第三条记录,开始扫描右表,根据条件t.parent_id = s.type_id总共匹配到一条记录,将两边匹配的记录合为一条记录存入到连接结果集中。
依次继续执行,直到根据左表最后一条记录扫描完右表最后一条记录,搜索结束。
左连接是要完整显示左表的数据的,所以即便在右表中未找到匹配的记录,依然要把这种情况反映出来。
最后SELECT将需要的字段从连接结果集中查找,得到最终结果集。
结果如下:
当使用右连接时,系统根据右表的记录去扫描左表的记录。
右连接:
select t.type_name as T_typename,s.type_name as S_typename from tdb_goods_types as t
right join tdb_goods_types as s
on t.parent_id = s.type_id;
具体过程如左连接类似。对于右表的每一条记录,在左表中逐条扫描,直到全部扫描完毕。
右表中的某条记录在左表中匹配到多条记录时,这些记录都要保存到连接结果集中。但若未匹配到时,需要生成为NULL的左表列。
右表连接的结果看起来有点别扭,可以认为是“查询右表的分类有哪些子分类”的结果。
内连接:
而当使用内连接时,根据内连接的定义,左表和右表任选一个作为父表,另一个作子表。根据父表去逐条扫描子表,在子表中未匹配到时,则也放弃父表的该条记录(因为不是符合连接条件t.parent_id = s.type_id的记录),继续执行,直到全部扫描完。
select t.type_name as T_typename,s.type_name as S_typename from tdb_goods_types as t
inner join tdb_goods_types as s
on t.parent_id = s.type_id;
内连接的结果:
当前水平有限,欢迎前辈指正!