文章目录
1.内联接
内联接实际上就是借助where谓词对两种表产生的笛卡儿积进行筛选,我们上面学习的查询都是内联接,也是在开发过程中使用的最多的联接查询
select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件;
案例:显示职工SMITH的名子和部门名称
SMITH的名子在职工表, 部门名称在部门表当中, 这里是多表查询
粗暴写法:将职工表和部门表做笛卡尔积,然后过滤非法数据,然后再进行条件筛选,显示我们想要的列
聪明做法:在职工表当中把SMITH职工的名子和部门号查询下来,当成一张新表 ,然后和部门表做笛卡尔积, 然后按照 部门号要相同进行过滤非法数据 ,之后得到的就是SMITH职工在部门表的数据
做法2:使用内联接, 把职工表和部门表做内联接
这3种写法都可以,但是它们还是有一些区别:
最下边的写法是: 先生成两张表的笛卡尔积,然后再按照where旁边的条件进行过滤.inner join ... on 条件则是依据on旁边的条件emp.deptno=dept.deptno and ename='SMITH',在生成笛卡尔积时就进行过滤,不满足这种条件的元组不会生成笛卡尔积.第一种写法 和第二种写法 它们的意义也不同,使用on的时侯:是按照两个条件再生成笛卡尔积的时侯就进行过滤非法数据, 改成where之后, inner join ... on 条件依据的条件则是先按照on旁边的条件, emp.deptno=dept.deptno进行过滤生成笛卡尔积以后,然后再筛选where ename='SMITH'.
在使用内联接过滤笛卡尔集中非法数据的时侯,我们是直接抛弃的,如果是左外联接,就不能直接抛弃,需要将右半部份置空并保留出来,反之右外联接
2.外联接
外联接就是为了显示出匹配不上的数据,从而确定什么数据不满足条件
测试表:
--建两张表
create table stu(id int,name varchar(30));--学生表
insert into stu values(1,'jack'),(2,'tom'),(3,'kity'),(4,'nono');
create table exam(id int,grade int);--成绩表
insert into exam values(1,56),(2,76),(11,8);
通过字段id来关联这两个表,因为没有加字段约束,所以exam表中存在一个id为11的中学生,这个中学生是非法的
如果单纯的进行内联接+条件过滤: 只有左表和右表匹配的信息,满足过滤条件才能显示下来
(1)左外联接
如果联合查询,左侧的表完全显示我们就说是左外联接,拿着左表的信息去右表筛选,满足的都要显示下来
左外联接和内联接几乎没有区别,唯一的区别就是,拿着左表的数据到右表进行拼接,如果匹配不上不会过滤右表数据而是置空显示
select 字段名 from 表名1 left join 表名2 on 连接条件;
案例: 查询所有中学生的成绩,如果这个中学生没有成绩,也要将中学生的个人信息显示下来
需求:找到非法存在的中学生
err写法:
注意:不能使用and,如果使用and的话, exam.id = stu.id and stu.id is null,这样在生成笛卡尔积时就进行过滤,不满足这种条件的元组不会生成笛卡尔积 ,然而stu表当中并没有id为空的,所以不会有结果,右表都是空信息
正确写法:
使用where此时是先按照的条件则是先按照id相同进行过滤, 然后再按照stu表当中id为空进行筛选.
(2)右外联接
如果联合查询,右侧的表完全显示我们就说是右外联接,
select 字段 from 表名1 right join 表名2 on 连接条件;
案例: 对stu表和exam表联合查询,把所有的成绩都显示下来,即使这个成绩没有中学生与它对应,也要显示下来
需求:如果想要找到没有出席考试的朋友 -> 即在前面的查找数据当中找到成绩表当中没有成绩的朋友
案例:列出部门名称和那些部门的职工信息,同时列举没有职工的部门
要列举没有职工的部门 -> 以部门表为主表,在职工表上面找, 如果有职工就拼接,没有找到职工,那么这个部门保留,员工为NULL
因为以部门表作为主表,所以假如部门表在右边,就写成左外联接, 否则写成右外联接
需求:如果想找到没有职工的部门: 在里面查找下来的数据中,找到职工表当中的职工编号是空的就是了
3.小结
查询的时侯,有大几率会涉及多张表,往往须要把多张表"合并"成一张表,所有查询的本质都是转化为一张表的查询