顾名思义就是多张表同时进行查询(之前了解过的DQL语句是基于单表查询)。
关系:如一个人只对应一张身份证,一张身份证只对应一个人。
实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一(UNION)。
关系:如一个员工对应一个部门,一个部门对应多个员工。
实现:在多的一方建立外键,指向一的一方的主键。
关系:如一个学生可以有多个老师,一个老师也可以有多个学生。
实现:建立第三张中间表,其至少包含两个外键分别对应两个多方的主键。
1.描述
2.多表查询分类
2.1 连接查询
相当于查询两表交集部分的数据
左外连接:查询左表所有数据,以及两张表交集部分数据
右外连接:查询右表所有数据,以及两张表交集部分数据
自连接查询:当前表与自身的连接查询(自连接必须使用表别名),就是自己连接自己,也就是把一张表连接查询多次。
联合查询:对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。
2.2 子查询
SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询。
标量子查询:子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式
列子查询:子查询返回的结果是一列(可以是多行)。
行子查询:子查询返回的结果是一行(可以是多列)。
表子查询:子查询返回的结果是多行多列。
相当于查询两表交集部分的数据
SELECT 字段列表 FROM 表1 , 表2 WHERE 条件 … ;
例查询每一个员工的姓名 , 及关联的部门的名称
表结构: emp , dept
连接条件: emp.dept_id = dept.id
SELECT 字段列表 FROM 表1 [ INNER ] JOIN 表2 ON 连接条件 … ;
例查询每一个员工的姓名 , 及关联的部门的名称
表结构: emp , dept
连接条件: emp.dept_id = dept.id
查询结果与上图无二异。
注意:
一旦为表起了别名,就不能再使用表名来指定对应的字段了,此时只能够使用别名来指定字段。
左外连接:查询左表所有数据,以及两张表交集部分数据
右外连接:查询右表所有数据,以及两张表交集部分数据
SELECT 字段列表 FROM 表1 LEFT [ OUTER ] JOIN 表2 ON 条件 … ;
例查询emp表的所有数据, 和对应的部门信息
表结构: emp, dept
连接条件: emp.dept_id = dept.id
例查询dept表的所有数据, 和对应的员工信息
表结构: emp, dept
连接条件: emp.dept_id = dept.id
注意:
左外连接和右外连接是可以相互替换的,只需要调整在连接查询时SQL中,表结构的先后顺序就可以了。
SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件 … ;
例1查询员工 及其 所属领导的名字
表结构: emp
例2查询所有员工及其领导的名字 , 如果员工没有领导, 也需要查询出来
表结构: emp
注意:
(1)对于自连接查询,可以是内连接查询,也可以是外连接查询。
(2)在自连接查询中,必须要为表起别名,(要不然我们不清楚所指定的条件、返回的字段,到底是哪一张表的字段。)
SELECT 字段列表 FROM 表A …
UNION [ ALL ]
SELECT 字段列表 FROM 表B …;
例将薪资低于 5000 的员工 , 和 年龄大于 50 岁的员工全部查询出来。
但是通过上图查询结果可以看出并未去重(第1行和第8行),所以**union all查询出来的结果,仅仅进行简单的合并,并未去重。**则可通过如下语句:
注意:
(1)对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致;
(2)union all会将全部的数据直接合并在一起,union会对合并之后的数据去重。
SELECT * FROM t1 WHERE column1 = ( SELECT column1 FROM t2 );
子查询外部的语句可以是INSERT / UPDATE / DELETE / SELECT 的任何一个。
根据子查询位置分有WHERE之后、FROM之后、SELECT之后;
根据子查询结果不同,分有如下几类:
子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式。
常用的操作符:= <> > >= < <=
例1 查询 “销售部” 的所有员工信息.
我们可以分解为两步:
先查询“销售部”的部门ID,再根据该部门ID查询所有员工信息。
例2查询在 “方东白” 入职之后的员工信息
我们可以分解为两步:
先查询“东方白”的入职时间,再查询指定日期之后入职的所有员工信息
子查询返回的结果是一列(可以是多行)。
例1查询 “销售部” 和 “市场部” 的所有员工信息
我们可以分为两步:
先查询“销售部”和“市场部”的部门ID,再根据部门ID查询所有员工信息
例2查询比“财务部”所有人工资都高的员工信息
我们可以分解为两步:
先查询所有财务部人员工资(这里也可以分成先查询“财务部”的部门ID,再根据部门ID查询员工工资),再查询比“财务部”所有人员工资都高的员工信息
例3查询比“研发部”其中任意一人工资高的员工信息
我们可以分解为两步:
先查询“研发部”所有人员工资,再查询比“研发部”其中任意一人工资都高的员工信息
子查询返回的结果是一行(可以是多列)。
常用的操作符:= 、<> 、IN 、NOT IN
例 查询与 “张无忌” 的薪资及直属领导相同的员工信息
我们可以分解为两步:
先查询“张无忌”的薪资和直属领导,再查询与该员工的薪资和直属领导相同的员工信息
子查询返回的结果是多行多列。
常用的操作符:IN
例1查询与 “鹿杖客” , “宋远桥” 的职位和薪资相同的员工信息
我们可以分解为两步:
先查询“鹿杖客”,“宋远桥”的职位和薪资。再查询与该两位职位和薪资相同的员工信息
例2查询入职日期是 “2006-01-01” 之后的员工信息 , 及其部门信息
我们可以分解为两步:
先查询入职日期是 “2006-01-01” 之后的员工信息,再查询该部分员工对应的部门信息。