文章目录
在实际的开发中,多表查询是非常常见的需求之一。SQL的多表查询语句能够实现多张表之间的关联查询,使用起来非常灵活。而子查询则是SQL中极为重要的一种查询方式,可以将子查询的结果作为另一个查询的条件或结果进行操作。本文将详细介绍SQL中的多表查询语句和子查询,包括内连接查询、外连接查询、自连接查询以及不同类型的子查询,帮助读者更好地掌握SQL的查询语法。
在多表查询方面,本文将介绍多种常见的查询方式,包括隐式内连接、显示内连接、左外连接、右外连接、自连接等。每种查询方式都会配有详细的语法和演示案例,帮助读者更好地理解和掌握。在子查询方面,本文将详细介绍标量子查询、列子查询、行子查询、表子查询等多种类型的子查询,以及它们的使用场景和语法规则。
无论是在日常开发中的查询需求,还是在SQL的学习和使用中,多表查询和子查询都是非常基础且重要的内容。本文旨在通过详细的介绍和案例演示,帮助读者更好地理解和掌握SQL的多表查询语句和子查询,提高SQL的查询能力和应用水平。
多表查询分类
- 连接查询
- 内连接:相当于查询A、B交集部分数据
- 外连接:
- 左外连接:查询左表所有数据,以及两张表交集部分数据。
- 右外连接:查询右表所有数据,以及两张表交集部分数据。
- 自连接:当前表与自身的连接查询,自连接必须使用表别名
- 子查询
连接查询-内连接
内连接的查询语法(内连接查询的是两张表的交集部分):
-
隐式内连接
SELECT 字段列表 FROM 表1,表2 WHERE 条件 ...;
-
显示内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件 ...;
-
内连接演示
- 查询每一个员工的姓名,以及关联的部门名称(隐式内连接实现)
- 表结构:emp , dept
- 连接条件:emp.dept_id = dept.id
select emp.name,dept.name from emp , dept where emp.dept_id = dept.id;
- 查询每一个员工的姓名,以及关联的部门名称(显式内连接实现)
- 表结构:emp , dept
- 连接条件:emp.dept_id = dept.id
select e.name,d.name from emp e inner join dept d on e.dept_id = d.id; e和d是别名
连接查询-外连接
外连接的查询语法
-
左外连接(相当于查询表1(左表)的所有数据 包含 表1和表2交集部分的数据)
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件 ... ;
-
右外连接(相当于查询表2(右表)的所有数据 包含 表1和表2交集部分的数据)
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件 ... ;
-
外连接演示
- 查询emp表的所有数据,和对应的部门信息(左外连接)
- 表结构:emp , dept
- 连接条件:emp.dept_id = dept.id
select e.*,d.name from emp e left outer join dept d on e.dept_id = d.id;
- 查询dept表的所有数据,和对应的员工信息(右外连接)
- 表结构:emp , dept
- 连接条件:emp.dept_id = dept.id
select d.*,e.* from emp e right outer join dept d on e.dept_id = d.id;
连接查询-自连接
自连接的查询语法(自连接查询,可以是内连接查询,也可以是外连接查询)
SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件...;
-
自连接演示
- 查询员工 及其 所属领导的名字
- 表结构:emp
select a.name,b.name from ema a ,emp b where a.managerid = b.id;
- 查询所有员工 emp 及其领导的名字 emp ,如果员工没有领导,也需要查询出来
- 表结构:emp.a , emp.b
select a.nme '员工' , b.name '领导' from emp a left join emp b on a.managerid = b.id;
联合查询-union,union all
对于union 查询,就是把多次查询的结果合并起来,形成一个新的查询结果集
注意:对于联合查询的多张表的列数必须保持一致吗,字段类型也需要保持一致。
union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重
SELECT 字段列表 FROM 表A ...
UNION[ALL]
SELECT 字段列表 FROM 表B ...;
-
查询演示
- 将薪资低于 5000 的员工,和年龄大于 50 岁的员工全部查询出来
select * from emp where salary < 5000 union all //查询时如果需要去重则直接把all去掉即可 select * from emp where age > 50;
子查询
概念:SQL 语句中嵌套SELECT语句,称为嵌套查询,又称子查询。
子查询外部的语句可以是INSERT / UPDATE / DELETE / SELECT 的任何一个。
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
-
根据子查询结果不同,分为:
- 标量子查询(子查询结果为单个值)
- 列子查询(子查询结果为一列)
- 行子查询(子查询结果为一行)
- 表子查询(子查询结果为多行多列)
-
根据子查询位置,分为:WHERE之后、FROM之后、SELECT之后。
标量子查询
子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询
常用的操作符:= <> > = < < =
-
查询 “销售部” 的所有员工信息
select * from emp where dept_id = (select id from dept where name = '销售部');
列子查询
子查询返回的结果是一列(可以是多行),这种子查询称为列子查询。
常用的操作符:IN 、 NOT IN 、 ANY 、SOME 、ALL
操作符 | 描述 |
---|---|
IN | 在指定的集合范围之内,多选一 |
NOT IN | 不在指定的集合范围内 |
ANY | 子查询返回列表中,有任意一个满足即可 |
SOME | 与ANY等同,使用SOME的地方都可以使用ANY |
ALL | 子查询返回列表的所有值都必须满足 |
- 根据部门ID,查询员工信息(销售部市场部所有员工信息)
select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部');
- 查询比财务部所有人工资都高的员工信息
select * from emp where salary > all (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 = '研发部'));
行子查询
子查询返回的是一行(可以是多列),这种子查询称为行子查询
常用操作符: = 、<> 、IN 、NOT IN
- 查询与 ‘张三’ 的薪酬及直属领导相同的员工信息
select * from emp where (salary,managerid) = (select salary,managerid from emp where name = '张三');
表子查询
子查询返回的结果是多行多列,这种子查询称为表子查询
常用的操作符:IN
- 查询与“张三”,“李四”的职位和薪资相同的员工信息
select * from emp where (job,salary) in (select job,salary from emp where name = '张三' or name = '李四');
可以使用 DISTINCT 关键字对查询结果进行去重。
在SQL语句中,可以使用 DISTINCT
关键字对查询结果进行去重。
例如,要查询所有员工所在的部门,可以使用以下SQL语句:
SELECT DISTINCT dept_id FROM emp;
这将返回一个包含所有不同部门ID的列表,其中每个ID只出现一次。
多表关系(总结)
一对多 | 在多的一方设置外键,关联一的一方的主键 |
---|---|
多对多 | 建立中间表、中间表包含两个外键,关联两张表的主键 |
一对一 | 用于表结构拆分,在其中任何一方设置外键(UNIQUE),关联另一方的主键 |
多表查询(总结)
内连接
隐式:SELECT...FROM 表A,表B WHERE 条件...
显示:SELECT...FROM 表A INNER JOIN 表B ON 条件...
外连接
左外:SELECT...FROM 表A LEFT JOIN 表B ON 条件...
右外:SELECT...FROM 表A RIGHT JOIN 表B ON 条件...
自连接:SELECT...FROM 表A 别名1,表A 别名2 WHERE 条件...
子查询:标量子查询、列子查询、行子查询、表子查询