目录
·多表关系
·一对多(多对一)
·多对多
·一对一
·多表查询概述
什么是多表查询
例子:
多表查询的分类:
连接查询:
子查询:
·内连接
内连接查询语法:
隐式内连接:
显示内连接:
需求演示:
·外连接
外连接语法:
左外连接:
例子:
右外连接:
例子:
·自连接
自连接语法:
例子:
·联合查询-union,union all
语法:
例子:
·子查询(嵌套查询)
·概念:
·根据子查询的结果不同,分为:
1、标量子查询(查询结果为单个值)
例子:
2、列子查询(查询结果为一列)
例子:
3、行子查询(查询结果为一行)
例子:
4、表子查询(查询结果为多行多列)
例子:
·根据子查询位置,分为:
·多表查询案例
之前讲过DQL语句讲解过单表查询,现在从7个方面讲解多表查询
·多表关系
在项目开发过程中,我们会根据业务需求,业务模块之间的关系,分析并设计标结果。由于业务之间是有各种联系的,所以表结构也有各种联系,基本分为三种:
·一对多(多对一)
比较典型的:部门和员工
关系:一个部门可以有多个员工,一个员工只有一个部门
实现方法:在多的一方建立外键,指向一的一方的主键。即将部门的id存在员工的里面当外键。
·多对多
典型案例:学生和课程
关系:一个学生可以选择多门课程,一个课程也可以被多个学生选择。
实现方式:建立一张中间表,用来存储学生id和课程id,这样可以看到学生选择了那些课,也可以看到一个课有哪些学生。
·一对一
案例:用户和用户详情的关系
关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率
实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE),这是为了避免外键重复会变成一对多,加了约束就保证是一对一的关系。
·多表查询概述
什么是多表查询
从多张表进行数据的查询
例子:
查询员工emp和对应的部门dept之间的数据
select * from emp, dept where emp.dept_id = dept.id;
#直接查询emp和dept 表: select * from emp, dept ; 出现的结果会是emp和dept两张表数据的排列组合,然后加上条件:dept_id = dept.id,让emp的外键和dept的主键相等,就是我们想要的结果。
多表查询的分类:
连接查询:
内连接:相当于查询A,B交集部分数据
外连接:
左外连接:查询左表所以数据,以及两张表交集部分数据
右外连接:查询右表所有数据,以及两张表交集部分数据
自连接:当前表与自身的连接查询,自连接必须使用表别名
子查询:
·内连接
内连接查询语法:
隐式内连接:
SELECT 字段列表 FROM 表1 ,表2 WHERE 条件....;
显示内连接:
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件....;
#内连接查询的是两张表交集的部分
需求演示:
1、查询每一个员工的姓名,及关联的部门的名称(隐式内连接)
select emp.name,dept.name from emp , dept where emp.dept_id = dept.id;
select e.name , d.name from emp e , dept d where e.dept_id = d.id;
2、查询每一个员工的姓名,及关联的部门名称(显示内联接)
select e.name, d.name from emp e inner join dept d on e.dept_id = d.id;
·外连接
外连接语法:
左外连接:
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件...:
#查询结果是表1(左表) 的所有数据 包含 表1 和表2交集部分的数据。
例子:
查询emp表的所有数据 和 对应的部门的信息(左外连接)
select e.* ,d.name from emp e left outer join dept d on e.dept_id = d.id;
右外连接:
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件...:
#查询结果是表2(右表) 的所有数据 包含 表1 和表2交集部分的数据。
例子:
查询dept表的所有数据 和 对应的员工的信息(右外连接)
select d.*, e.* from emp e right outer join dept d on e.dept_id = d.id;
#右外也可以改成左外 right 改left ,把两个表交换位置
#select d.*, e.* from dept d left outer join emp e on e.dept_id = d.id;
·自连接
自连接语法:
SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件....;
#自连接,可以是内连接查询,也可以是外连接查询。
例子:
1、查询员工和其领导信息:
select e.name, e1.name from emp e join emp e1 on e.managerid = e1.id;
#即把表emp当做两张表,进行查询即可。使用的依旧是内连接和外连接的语句。都可以用。
·联合查询-union,union all
对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集
语法:
SELECT 字段列表 FROM 表A...
UNION [ALL]
SELECT 字段列表 FROM 表B...;
#字段列数必须一致,类型也要一致,不能说上面返回8列数据,下面就返回一列数据。
例子:
将薪资低于5000的员工和年龄大于50的员工查询出来。
select * from emp where salary < 5000
union
select * from emp where age > 50
结果:1-5是工资低于5000的,6-8是年龄大于50的,而不是两个条件都满足,是把两张表合并,拼在一起。
#如果使用 union all 进行合并,是直接合并,像上面的鹿杖客就出现了两次。
#使用 union 可以把重复出现的数据进行去重。
·子查询(嵌套查询)
·概念:
SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
括号里是子查询的外联语句,外联语句可以是INSERT/UPDATE/SELECT中的任意一个。
·根据子查询的结果不同,分为:
1、标量子查询(查询结果为单个值)
标量子查询返回的结果是单个值(数字,字符串,日期等),最简单的形式,这种子查询称为标量子查询。
常用的操作符:= <>(不等号) > >= < <=
例子:
1、查询“销售部”的所有员工信息
先查出销售部的id,id是单个值,再查所有人
select * from emp where dept_id = (select id from dept where name = '销售部');
2、查询“房东白“入职后的员工信息
先查方东白的入职日期,再查这个日期之后入职的员工。
select * from emp where entrydate > (select entrydate from emp where name = '方东白');
2、列子查询(查询结果为一列)
子查询返回的结果是一列,可以是多行
常用操作符:
操作符 | 描述 |
IN | 在指定的集合范围内,多选一 |
NOT IN | 不在指定的集合范围之内 |
ANY | 子查询返回的列表中,有任意一个满足即可 |
SOME | 与ANY相同,用SOME的地方都可以用ANY |
ALL | 子查询返回列表的所有值都必须满足 |
例子:
1、查询‘市场部’和‘销售部’所有员工信息
select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部');
2、查询比财务部所有人工资都高的员工信息
首先查询所有财务部人工资,
select salary from emp where dept_id = (select id from dept where name = '财务部')
然后比所有财务部人工资都高
select * from emp where salary > all(select salary from emp where dept_id = (select id from dept where name = '财务部'))
3、比研发部任意一个员工工资高的员工信息
select salary from emp where dept_id = (select id from dept where name = '研发部')
select * from emp where salary > any (select salary from emp where dept_id = (select id from dept where name = '研发部'));
3、行子查询(查询结果为一行)
子查询结果返回的是一行(可以是多列),这种子查询称为行子查询。
常用的操作符:= <> IN NOT IN
例子:
查询与“张无忌”的薪资和直属领导相同的员工信息
先查询张无忌的薪资和直属领导
select salary , managerid from emp where name = '张无忌';
再查询条件相同的员工
select * from emp where (salary, managerid) = (select salary , managerid from emp where name = '张无忌');
4、表子查询(查询结果为多行多列)
指子查询返回的结果是多行多列,
常见操作符: IN
这种方法中通常把得到的结果作为一张表进行查询
例子:
1、查询和‘鹿杖客’,‘松远桥’职位和薪资相同的员工信息
先查出职位和薪资
select job, salary from emp where name = '鹿杖客' or name = '松远桥';
再查相同
select * from emp where (job , salary) in (select job, salary from emp where name = '鹿杖客' or name = '松远桥')
2、查询入职日期在‘2006-01-01’之后的员工信息,及其部门信息
select * from emp where entrydate > '2006-01-01';
select e.* , d.* from (select * from emp where entrydate > '2006-01-01') e left join dept d on e.dept_id = d.id;
·根据子查询位置,分为:
WHERE之后
FROM之后
SELECT之后