MySQL内外链接
- 内连接
- 显示SMITH的名字和部门名称
- 外连接
- 左外连接
- 查询所有学生的成绩,如果这个学生没有成绩,也要将学生的个人信息显示出来
- 右外连接
- 把所有的成绩都显示出来,即使这个成绩没有学生与它对应,也要显示出来
- 列出部门名称和这些部门的员工信息,同时列出没有员工的部门
内连接
什么是内连接:
在以前我们直接利用from子句对多个表做笛卡尔积的时候,MySQL会无脑的将一张表中的每一条数据与另一张表中的所有数据进行连接,然后形成一张新表,然后再由我们自己利用where子句筛选出有意义的数据,这实际上是内连接的一种,而实际上我们可以在连接的时候让MySQL不要无脑连接,可以让MySQL将满足条件的数据连接起来,这样的话我们就得到了一张有意义的表,我们就不用自己在where子句中进行筛选了,这也是内连接的一种,如果某个表中没有与另一个表匹配的数据,那么该表的数据将不会出现在结果集中。这样做的语法如下:
select 字段 from table1 inner join table2 on 连接条件;
显示SMITH的名字和部门名称
分析:
方法一:
首先我们要的数据来自于emp表和dept表,那么我们可以对这两个表做笛卡尔积,然后筛选出有意义的数据,并且ename=’SMITH‘的数据;
SQL语句:
select ename,dname from emp,dept where emp.deptno<=>dept.deptno and ename='SMITH';
这里是利用了前面学习的多表查询的方式,这也是内连接的一种;
方法二:
根据我们上述学的新知识,我们在连接的时候就可以按照条件连接,然后再筛选出ename=“SMITH”的数据;
SQL语句:
select ename,dname from emp inner join dept on emp.deptno<=>dept.deptno where ename="SMITH" ;
实际上我们也可以在连接条件里面加上ename='SMITH’这一个条件:
select ename,dname from emp inner join dept on emp.deptno<=>dept.deptno and ename='SMITH';
这样写的话我们就不用在where子句中进行筛选了,但是我们不建议这样写因为这种写法逻辑上没有使用where子句的写法清晰,使用where子句的写法更符合我们的编码逻辑;
外连接
在MySQL中外连接分为左外连接和右外连接
什么是外连接:
在内链接中某个表的数据与另一个表的数据在连接的时候没有匹配的数据,那么这个表中的数据是不会出现在结果集中的,但是在外连接中不是这样的,在外连接中如果某个表的数据在另一个表中没有满足条件的连接,那么这个表中的数据依然会存在与最后的结果集中,尽管其在另一个表中没有与之匹配的数据;
因此对于左外连接来说:就是在最后的结果中会显示左表中的全部数据,尽管左表中的数据在右表中没有与之匹配数数据;
对于右外连接同理:就是在最后的结果中会显示右表中的全部数据,尽管右表中的数据在左表中没有与之匹配数数据;
//创建两张表
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);
左外连接
语法:
select 字段 from table1 left join table2 on 连接条件;
这里我们解释一下那个是左表,那个是右表:
table1是左表,table2是右表,从编码顺序上来区分的;
查询所有学生的成绩,如果这个学生没有成绩,也要将学生的个人信息显示出来
分析:
最后要求我们查询的数据来自stu表、exam表 因此我们肯定需要多表查询,然后的话我们又要我们显示所有学生的成绩,尽管这个学生在exam表中没有成绩,那么我们就可以将stu当作左表,exam当作右表进行左外连接;
SQL语句:select stu.id,name,grade from stu left join exam on stu.id<=>exam.id;
右外连接
语法:
select 字段 from table1 right table2 on 连接条件;
把所有的成绩都显示出来,即使这个成绩没有学生与它对应,也要显示出来
分析:
最后要求的信息有成绩、学生姓名,学生id,然后这两个信息分别来自exam表、stu表,因此我们肯定是需要做联合查询的,这个没话说,然后的话又要我们显示所有成绩,即该成绩在学生表中没有学生与之对应,那么我们可以将exam表当作右表来进行右连接:
SQL语句:
select exam.id,name,grade from stu right join exam on exam.id<=>stu.id;
实际上利用左外连接查询也是可以的,将exam当左表:
SQL语句:
select exam.id,name,grade from exam left join stu on exam.id<=>stu.id;
实际上:还有一个全外连接的,全外连接就是左外连接与右外连接的结合,左表中的数据和右表中的数据会全部显示在最后的结果集中;
但是MySQL还没有支持全外连接,只有左外连接、右外连接;
列出部门名称和这些部门的员工信息,同时列出没有员工的部门
分析:
最后需要我们显示的有部门名、以及员工信息,那么我们需要的数据来自于dept表、emp表我们需要对这两张表做联合查询,同时题目要求我们显示所有部门,即使这个部门没有员工,那么我们就可以让dept表充当左表,然后以左外连接的方式来进行数据连接筛选:
SQL语句:
select dname,emp.* from dept left join emp on dept.deptno<=>emp.deptno;
右外连接与内连接的写法读者可以自行尝试一下;