多表查询
概述:从多张表中查询数据
笛卡尔积:在数学中,两个集合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);
根据子查询结果不同,分为:
标量子查询(子查询结果为单个值)
常用操作符:> < = ...
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 之后