4.4 数据表的内连接

本次课程我们将学习从两张数据表里边查询数据,总算是摆脱了从一张数据表里边查询数据,接下来我们就开始学习表连接的语法。从多张数据表里面查询数据必须要指定关联的条件。

1. 从多张表中提取数据 

1.1 从多张表中提取数据,必须指定关联的条件,如果不定义关联条件就会出现无条件连接,两张表的数据惠交叉连接,产生笛卡尔积

比如说某个员工的deptno是10,它的跟部门表里边10的部门记录做连接。这个就是连接条件。如果不规定连接条件,那可就是无条件的去连接两张表的记录了。数据就会交叉结合,产生笛卡尔积。比如说下面这个sql语句,用join关键字把这个员工表和部门表联系在一起,但是并没有给出记录之间的连接条件。在查询出来以后,最终的这个结果,大家看出现了56条记录,也就是员工表里面有14条记录,部门表里边有四条记录。所以说笛卡尔级的这个结果集里边就出现了56条记录,也就是拿每个员工的记录与每个部门的记录做连接,这个是不符合现实逻辑的。所以说我们在做表连接的时候,一定要给出连接条件才行。

1.2 规定了连接条件的表连接语句,就不会出现笛卡尔积

如果规定了表连接的条件,结果集里边就不会出现笛卡尔集了,还是刚才的这个SQL语句,只是在后面加上了一个on这样的子句,规定了一下连接的条件。那么这个连接条件是员工的部门编号和部门的部门编号是要相等的。这就是一个两张表的连接条件。但是有一个问题就是员工表里边有deptno, 这个字段在部门表里边也有这个字段。 

问题1:查询每个员工的部门信息

因为是想查询每名员工的部门信息,里边是包含了员工的编号,员工的名字,还有是部门的名称。前两个字段是从员工表里边可以得到相关的数据,但是部门名称我们必须要查询部门表,才能得到相关的数据。所以说我现在的查询语句要从员工表和部门表里边联合去查询,所以说就必须要用表连接才行了。

两张表通过部门编号deptno进行连接

select
e.empno,e.ename,d.dname
from t_emp e join t_dept d
on e.deptno=d.deptno

2. 表连接的分类

表连接,一共分为两种,一种叫做内连接,另外一种叫做外连接。

内连接是结果集中只保留符合连接条件的记录,不符合连接条件的记录是绝对不会出现在结果集里边的。

外连接是不管符不符合连接条件记录,都是要保留在结果集里边。也就是说符合连接条件的记录会出现在结果集里边。不符合连接条件的记录,也会出现在结果集里边。

内连接用于查询多张关系表里边符合条件的记录。就像下面这个图示表现的那样,链接会查找出两张数据表交集的部分。也就是说,符合连接条件的记录。比如说我们刚才做表连接的SQL练习,就没有看到40部门里边的员工,因为40部门是没有人的,所以在连接时无法和员工表做连接了,不符合连接条件的记录,是绝对不会出现在结果集里边。

接下来我们看一下内连接的具体语法。在from子句里边,我们要连接多张表的时候,表和表之间写上join这个关键字就行了。其实join这个关键字的完整的写法叫做inner join,只是说in的这个关键字可以忽略,可以不写,所以就简写成了这个表1,然后join表2,然后用on子句规定一下这个连接条件就行了,如果连接三张表,那就继续的join,连接第三张表,然后写上这个连接条件就可以了

3. 内连接的多种语法形式

我们先看第一个SQL的语法,这个是我们看到最标准的内连接语法。用JOIN关键字来连接两张表,让子句规定连接的条件;

第二种:条件是用来筛选符合条件记录的,把on子句的条件写在where子句里边,于是就有了下面这种语法,忽略了on子句,用where去替代,把连接条件的定义到where里边儿。所以说这个是内连接的另外一种写法

第三种:基于这种写法又衍生出来第三种写法就是把子句里边就写上表名就行了,然后用逗号把它们分开,最后在where里边定义好这些数据表的连接条件就行了

内连接练习1:查询每个员工的工号,姓名,部门名称,底薪,职位,工资等级 

要从三张数据表里面来提取字段信息部门名称是来自于部门表,工资等级是来自于工资等级表,剩下的字段是来自于员工表,那么三张表的连接应该怎么去写sql语句呢

员工表                                        部门表                                             工资等级表

发现上面3个表并没有相同的字段,那应当如何连接呢?

其实没有同名的字段,不代表说表连接,没有办法去连接查询数据,是可以的,只是这个条件,你要找到逻辑关系就行了。咱们的这个员工表,有sal这个字段就是底薪。那咱们看一下工资等级表里边儿。第一个字段是工资的等级,一共是分五个级别。咱们看第一个级别,它的这个工资等级是最低的底薪,是700元,最高的底薪是1200元。所以说我们在连接两张表的时候,只要规定咱们的这个sal,符合这个low sal和high sal之间的这么一个底薪范围就可以了。所以即使没有相同字段我们也可以将两张表连接起来。

内连接的数据表并不一定要有同名字段,只要字段之间符合逻辑关系就可以。

select
e.empno,e.ename,d.deptno,d.dname,e.sal,e.job,s.grade
from t_emp e join t_dept d on e.deptno=d.deptno
join t_salgrade s on e.sal between s.losal and s.hisal;

 内连接练习2:查询与SCOTT相同部门员工都有谁

这个题里面蕴含了两个未知条件。第一个未知是不知道Scott部门是什么。第二个未知是谁跟Scott是同一个部门的,

第一种方法:如果用子查询的语法,我们先把Scott部门给查出来,再去查询谁跟scott是同一个部门的,子查询它的好处就是非常符合咱们思考的逻辑,数据库在执行这个子查询的时候,它的速度是非常慢的

select
ename
from t_emp
where deptno=(select deptno from t_emp where ename="SCOTT") and ename != "SCOLL"

第二种方法:相同表做表连接,把员工表和员工表连接起来,连接条件通过部门编号,where条件表1过滤条件等于“SCOTT”,表2过滤条件不等于“SCOTT”,表内连接因为取的是两个表的交集,这个表连接,因为没有子查询,所以说他在用WHERE语句判断的时候,就根本就不用做很多次子查询,查询速度会快得多。

select
e2.ename
from t_emp e1 join t_emp e2 on e1.deptno=e2.deptno
where e1.ename="SCOTT" and e2.ename != "SCOTT";

相同的数据表也可以做表连接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值