Skip to content

多表查询

概述:从多张表中查询数据

笛卡尔积:在数学中,两个集合A集合和B集合所有的组合情况(多表查询时,需要消除无效的笛卡尔积)

连接查询

内连接:

查询A,B交集部分的数据

隐式内连接:

select 字段列表 from 表1,表2 where 条件... ;

显式内连接:

select 字段列表 from 表1 [inner] join 表2 on 连接条件... ;

外连接:

左外连接:查询左表中所有数据以及两张表交集部分数据

select 字段列表 from 表1 left outer join 表2 on 条件

右外连接:查询右表所有数据,以及两张表交集部分数据

select 字段列表 from 表1 right outer join 表2 on 条件

自连接:

当前表与自身的连接查询,自连接必须使用表别名

语法:

select 字段列表 from 表A 别名A join 表B 别名B on 条件;

联合查询

对于union查询,就是把多次查询的结果合并起来,形成一个新的结果集

select 字段列表 from 表A
union
select 字段列表 from 表B;

注意:

  • 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。

  • union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重

子查询

概念:SQL语句中嵌套select语句,称为嵌套查询,又称为子查询

语法:

select * from table1 where column1=(select column1 from table2);
子查询外部语句可以是 insert / update / delete / select 中的任何一个

根据子查询结果不同,分为:

标量子查询(子查询结果为单个值)

常用操作符:> < = ...

eg. 查询在“东方白”入职之后的员工信息
    select * from emp where entrydate<(select entrydate from emp where name='东方白');

列子查询(子查询结果为一列)

常用操作符:in, not in ,any ,some , all

操作符 描述
IN 在指定的集合范围之内,多选一
NOT IN 不在指定的集合范围之内
ANY 子查询返回列表中,有任意一个满足即可
SOME 与ANY相同,使用SOME的地方都可以使用ANY
ALL 子查询返回列表中的所有值都必须满足
eg.查询“销售部”和“市场部”的所有员工信息
select * from emp where dept_id in (select id from dept where name='销售部' or name='市场部');
eg.查询比财务部所有人工资都高的员工信息
--a 获取财务部部门id
select id from dept where name='财务部';
--b 查询财务部人员的工资
select salary from emp where dept_id=(select id from dept where name='财务部');
--c 查询比财务部所有人工资都高的员工信息
select * from emp where salary > all(select salary from emp where dept_id=(select id from dept where name='财务部'););
eg.查询比研发部其中任意一人工资高的员工信息
--a 查询研发部的部门id
select id from dept where name='研发部';
--b 查询研发部员工的工资
select salary from emp where dept_id=(select id from dept where name='研发部');
--c 查询比研发部其中任意一人工资高的员工信息
select * from emp where salary > any(select salary from emp where dept_id=(select id from dept where name='研发部'));

行子查询(子查询结果为一行)

常用操作符:= 、>< 、IN 、NOT IN

eg.查询与张无忌的薪资及直属领导相同的员工信息
-- a查询张无忌的薪资和直属领导
select salary,mangerid from emp;
-- b查询与张无忌的薪资及直属领导相同的员工信息
select * from emp where (salary,mangerid)=(select salary,mangerid from emp);

表子查询(子查询结果为多行多列)

eg.查询与“鹿杖客”,“宋远桥”的职位和薪资相同的员工信息
-- a查询“鹿杖客”,“宋远桥”的职位和薪资
select job,salary from emp where name='鹿杖客' or name='宋远桥';
-- b查询与“鹿杖客”,“宋远桥”的职位和薪资相同的员工信息
select * from emp where (job,salary) in (select job,salary from emp where name='鹿杖客' or name='宋远桥';);
eg.查询入职日期是“2006-01-01”之后的员工信息,及其部门信息
-- a
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 之后