数据库学习记录(二)多表设计与多表查询

一对多

一对多时候,一张表内的一个数据可能对应着其他表内的多个数据,例如一个部门内有多个员工,但是公司里不只一个部门,也不止一个员工,这个时候就是一对多的情况,这个时候可以绑定一个外键,让同一个部门内的员工与该部门实现绑定(该外键叫物理外键,不推荐使用,会影响数据库的使用效率和操作灵活性,一般在开发中使用逻辑外键处理该类问题

多对多

多对多表示一张表内的一个数据对应着另一张表内的多个数据,另一张表内的一个数据也对应着这张表内的多个数据,例如学生选课 ,一个学生能选多门课,而一门课也能被多个学生所选,所以这时候就需要一个中间表来解决这个问题,将一个学生的id键绑定给中间表的学生id上,课程绑定给中间表的课程id,这样就能实现多个学生对应多门课程,多门课程对应多个学生。

多表查询 

多表查询主要是在多表查询之后加上限制条件从而得到我们想要的数据

内连接

相当于查询下图的A,B之间的交集

隐式内连接主要是将限制条件写在where之后,从而实现多表查询数据的目的,例如:我需要在员工表和部门表中查询所有员工的姓名以及对应的部门信息 ,如下:

-- 查询员工的姓名,及其所属的部门名称
select tb_dept.name,tb_emp.name from tb_emp,tb_dept where tb_dept.id = tb_emp.job;

显式内连接就是将from后面的表信息用join相关字段进行替换,并在最后添加上on加连接条件

还是上面的例子,sql语句如下:

-- 使用内连接
select tb_dept.name,tb_emp.name from tb_emp inner join tb_dept  on tb_dept.id = tb_emp.dept_id;

 外连接(需要谁完全显示就将谁设置为相关连接的相关表)

左外连接就是会完全包括左边的数据,右外连接就是会完全包含右边的数据,所以在使用相关外连接时需要注意哪些数据是被完全包含的

左外连接就会显示所有的左边表的数据,且与右边表与之对应,如果左表没有与右表对应的数据,会自动将全部左表的数据打印出,右表相关数据显示为空 ,如下:

而同理,右外连接就是会显示所有的右边表的数据,如果右表中有左表没有对应的数据,则会将没有相关对应的左表数据显示为空

再例如我想查询员工表里的所有员工名字,以及对应的部门信息,但员工表内存在没有部门的员工,这时就将员工表作为左连接的左表,部门表作为左连接的右表,这时员工就算没有被分配部门,因为员工表是左连接的左表,所以所有的员工姓名会显示出,没有分配部门的员工部门为空

-- 使用左外连接查询所有员工的姓名,和对应的部门
select e.name,d.name from tb_emp e left join tb_dept d on e.dept_id = d.id

同理,我想查询所有部门的名字,即使部门里没有员工,也能被查询到,这个时候能将部门表作为左连接的左表或者右连接的右表,这样也能完全显示部门名字,这样的话也能将相关的数据完全显示在数据库的查询界面中。 

-- 使用右连接查询所有部门的名字,和对应的员工姓名
select e.name,d.name from tb_emp e right join tb_dept d on e.dept_id = d.id

子查询

子查询主要是sql语句的嵌套

就是先将一部分限制使用查询语句查出,再通过替代的方式将该部分语句放入查询语句中 

列子查询

例如:我需要查询教研部下的所有员工信息,因为我在员工表中保存部门是以数字的形式,那么我首先需要先在部门表中查询到教研部对应的数字,再在员工表里去查询部门为该数字的员工信息,此时就可以使用嵌套查询来结合这两个步骤,代码具体实现如下:

-- 查询教研部下所有员工的信息

select * from tb_emp where dept_id = (select id from tb_dept where name = '教研部');

如果需要多个查询限制的嵌套的话,需要使用in关键字来确定相关限制,因为=只能匹配一个限制条件,所以需要使用in来确定是否在一个范围中,如下:这样的话就能实现在一个限制条件范围内进行带有多个限制条件的查询

-- 查询教研部和咨询部所有的员工信息
select * from tb_emp where dept_id in (select id from tb_dept where name = '教研部'or name = '咨询部');

行子查询

例如在多个查询要求时,我们可以将多个条件绑定到一起进行查询,例如要求查询员工表里入职时间与工作职位与韦一笑相同的员工信息,先查询韦一笑的入职时间和工作职位,再查询员工表里与这些信息相匹配的员工信息。这样可以只执行一次子查询就能查询到相关的职工信息

-- 只出现一次的行子查询
select * from tb_emp where (entrydate,job) = (select entrydate,job from tb_emp where name = '韦一笑');

表查询

表查询返回的是多行多列,可以理解为一个临时表,使用代码如下,先将部分限制查询条件使用了之后,将查询出来的数据当表使用

-- 表子查询,查询入职日期是“2006-01-01'之后的员工信息,及其部门名称

select e.*,d.name from (select * from tb_emp where entrydate>'2006-01-01')e , tb_dept d where e.dept_id = d.id;

总结:

在实际开发中,经常使用多表查询,而不是简单的单一表查询,所有在一些查询操作中,多思考各个表之间的关系,以及题目的要求(例如分别对某个属性,表示就需要将表中的数据根据该属性进行分组),这样的话才能写出切合题目要求的查询语句。

  • 21
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值