连接查询概述
连接首先分为“无条件连接”和“有条件连接”,有条件连接又分为“等值连接”和“非等值连接”,在以上说到的这几种连接中,最重要的就是“等值连接”。
等值连接又分为“自然连接”和“外连接”,而外连接又分为“左外链接”和“右外链接”。
1、无条件连接
无条件连接其实就是广义笛卡尔乘积,即一个表(m行)中的每一行都与另外表(n行)中的每一行联合,最终构成了一个m*n行的一个表。
2、有条件连接
有条件连接顾名思义就是两个表之间的连接是有条件的,其中一个表的某一个字段与另外一个表中的某一个字段以某一种条件联系起来,连接的过程就是先扫面表1的第一行,去与表二中的每一行对比,满足条件的就选择出来,
然后拿表一中的第二行去做相同的操作,一直到最后完成。
很显然,这个连接后的表其实是广义笛卡尔乘积的子集。这种条件如果是不相等的话,那么就是非等值连接,反之就是等值连接。
非等值连接用的比较少,主要是等值连接。
等值连接
当一个表的某一个字段与另外一个表中的某一个字段的联系条件是相等的时候,那么这种连接就是等值连接。
在等值连接中,如果消除了重复的列,那么这样的等值连接就是自然连接。
在自然连接中,满足条件的才会被选出来成为新的行,不满足条件的是不会被选择出来的。其实自然连接就是内连接。
外链接
在两个表之间,如果某一张表的行与另外一张表对应的时候,出现了根据条件去筛选另外一张表的全部行,而前一张表仍有未对应的行,那么这些行是不会成为新表中的行的,但是如果想把这些没有对应的行显示出来,就要用到外连接了。
如果表一和表二连接,在表一中存在没有连接(没有对应的表二的内容)的行,表二中全部用NULL来补充,缺损的就是NULL,所以此时称为左外连接,反之则是右外连接。
左外连接:就是以左边的行为主,左边的全部都要显示出来,右边与之对应的要显示出来,没有与之对应的就补null。至于右边是否对应完了,不用考虑。
右外连接:就是以右边的行为主,右边的行要全部显示出来,左边与之对应的显示出来,没有对应的补null。至于左边是否对应完了,不用考虑。
两张表以上的连接查询:
对于两张表以上的内连接或者外连接,可以认为先让前面两张表连接起来,构成一个记录集,然后让把这个记录集当成新的表与后面的表相连接。
连接查询实例
内连接查询实例
方法一:用 = 内连接
select *from student select *from sc select *from course select student.*,sc.*,sc.Grade from student,sc where student.sno = sc.sno --表名.*表示的是选择了这个表中的所有列,所有列名都用了表名.列名 select student.*,course.*from student,sc,course where student.sno= sc.snoand sc.cno = course.cno --不管最终查询的列是否在某个表中,但是只要这个查询的条件中涉及到了这张表,那么就一定要在from中添加进来这张表
方法二:用 inner join 内连接
select student.*,sc.*from student inner join sc on student.sno = sc.sno select student.*,sc.*,course.* from student inner join sc on student.sno= sc.sno inner join courseon sc.cno= course.cno
以上是内连接的第二种写法.这个连接的过程是前面两张表先连接好了,然后再来连接第三张表。连接的条件已经在from里面了.当然,还可以用where来添加新的条件。
错误写法:
select student.* ,sc.* from student inner join sc where student.sno = sc.sno select student.*,sc.*,course.* from student inner join sc inner join course where student.sno = sc.sno and sc.cno = course.cno
外链接查询实例
select student.*,sc.* FROM Student left outer JOIN SCON Student.Sno= SC.Sno Where ……
select student.*,sc.* FROM Student right outer JOIN SCON Student.Sno= SC.Sno select student.*,sc.*,course.* FROM Student left outer JOIN SCON Student.Sno= SC.Sno right outer join course on SC.cno = course.cno
连接的条件已经在from里面了.当然还可以用where来添加新的条件
以下是错误的写法:
select student.* ,sc.* FROM Student left outer JOIN SC where Student.Sno = SC.Sno select student.* ,sc.*,course.* FROM Student left outer JOIN SC right outer join course where Student.Sno = SC.Sno and SC.cno = course.cno
内外混合连接查询实例
select student.*,sc.*,course.* FROM Student left outer JOIN SCON Student.Sno= SC.Sno inner join course on SC.cno= course.cno
实战三连发:
--查询文章被举报的次数 select itemId,count(itemId) from T_MakerArtiTipOff where itemType = 1 and status = 0 GROUP BY itemId --使用内连接(=)查询文章信息及被举报的次数 SELECT art.*,c.atoc FROM (select itemId,count(itemId) as atoc from T_MakerArtiTipOff where itemType = 1 and status = 0 GROUP BY itemId) as c,T_MakerArticle art WHERE c.itemId = art.Id --使用内连接(inner join)查询文章信息及被举报的次数 SELECT art.*,c.atoc FROM T_MakerArticle art inner join (select itemId,count(itemId) as atoc from T_MakerArtiTipOff where itemType = 1 and status = 0 GROUP BY itemId) as c on c.itemId = art.Id --使用左外连接查询文章信息及被举报的次数 SELECT art.Id, art.userGuid, u.upname, art.title, art.postTime, art.matchedTrade,c.atoc FROM T_MakerArticle art left outer JOIN (select itemId,count(itemId) as atoc from T_MakerArtiTipOff where itemType = 1 and status = 0 GROUP BY itemId) as c on c.itemId = art.Id left outer JOIN t_user u on art.userGuid = u.Guid
总结:
什么时候用内连接,什么时候用左外连接?
如果右侧表依赖于左侧表,而查询结果的立足点在于右侧表,而同时又需要左侧表的一些数据,那么,选择内连接。(比如左侧表是签到信息表,而右侧是签到记录表,而要查看签到记录信息时就可以用内连接)
如果右侧表依赖于左侧表,而查询结果关注的是左侧表,即要显示左侧表的每一条数据,但是可以没有对应的右侧表的数据与之对应。(比如左侧表是注册信息表,右侧表是实名信息表,当要查看每个注册用户的信息时就可以用左外连接)