多表查询
表关系和数据



相关知识点
sql
mark ->>> 内连接
- 查询两个表交集的部分
mark ->>> 外连接
- 左外连接, 查询左表所有的数据(包含两个表的交集部分, select * from A left join B, A 是左表, B是右表).
- 右外连接, 查询右表所有的数据(包含两个表的交集部分, select * from A right join B, A 是左表, B是右表, 所有的右连接都可以通过修改顺序变成左连接),
mark ->>> 自连接
- 当前表自身的连接查询, 自连接必须使用表别名
mark ->>> 联合查询
- 将两次的查询结果合并到一个查询结果中, 要求字段类型和字段列要一致
mark ->>> 子查询
- 标量子查询(子查询的结果为单行单列)
- 列子查询(子查询的结果为多行单列)
- 行子查询(子查询的结果为单行多列)
- 表子查询(子查询的结果为多行多列)
使用示例
sql
mark ->>> 内连接
// - 查询员工姓名以及关联的部门名称(隐式, 显示, 显示简写)
// - 隐式
select e.name, d.name from emp as e, dept as d where e.dept_id = d.id;
// -显示
select e.name, d.name from emp as e inner join dept as d on e.dept_id = d.id;
// - 显示简写
select e.name, d.name from emp as e join dept as d on e.dept_id = d.id;
mark ->>> 外连接
// - 查找emp所有的数据和对应的部门信息(左外)
select e.*, d.name from emp as e left join dept as d on e.dept_id = d.id;
// - 查找emp所有的数据和对应的部门信息(右外)
select d.*, e.* from emp as e left join dept as d on e.dept_id = d.id;
// - 查找emp所有的数据和对应的部门信息(左外)
select d.*, e.* from dept as d left join emp as e on e.dept_id = d.id;
mark ->>> 内连接
// - 查询员工及所属领导的名字
select e.name as 姓名, e1.name as 上司 from emp as e join emp as e1 on e.managerid = e1.id;
// - 查询员工及所属领导的, 所有没有领导, 则显示作者
select e.name as 姓名, case when e1.name is null then '无' else e1.name end as 上司 from emp as e left join emp as e1 on e.managerid = e1.id
// - 查询 年龄在40 - 60 之间 和 dept_id = 1 的人
// - 这里同一个条目会出现两次.
select * from emp where age > 40 and age < 60 union all select * from emp where dept_id = 1;
// - 去除重复的条目的.
select * from emp where age > 40 and age < 60 union select * from emp where dept_id = 1;
mark ->>> 子查询
// - 查询销售部所有的员工信息
// - 1.查询销售部的id
select id from dept where name = '销售部';
// - 2.查询 dept_id = 4 的员工信息
select * from emp where dept_id = 4;
// - 3.组合最终包含子查询的语句
select * from emp where dept_id = (select id from dept where name = '销售部');
// - 查询在方东白入职之后的入职的员工信息
// - 1.查询方东白的入职日期.
select entrydate from emp where name = '方东白';
// - 2.查询入职日期在 2009-02-12 之后的用户.
select * from emp where entrydate > '2009-02-12';
// - 3.组合最终包含子查询的语句.
select * from emp where entrydate > (select entrydate from emp where name = '方东白');
// - 查询销售部和市场部所有的员工信息
// - 1.查询市场部和销售部的id
select id from dept where name = '销售部' or name = '市场部';
// - 2.查询指定id的员工信息
select * from emp where dept_id in (2,4);
// - 3.组合最终包含子查询的语句
select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部');
// - 查询比财务部所有人工资都高的员工的信息
select *
from emp
where salary > (select max(salary) from emp where dept_id = (select id from dept where name = '财务部'));
// - 查询研发部其中任一人工资高的员工的信息
select *
from emp
where salary > (select min(salary) from emp where dept_id = (select id from dept where name = '研发部'));
// - 查询与张无忌薪资相同切与直属领导是同一人的用户
select * from emp where (managerid, salary) = (select managerid, salary from emp where name = '张无忌');
// - 查询与鹿杖客和宋远桥职位相同且薪资相同的用户的信息
select * from emp where (job, salary) in (select job,salary from emp where name in ('鹿杖客', '宋远桥'));
// - 查询入职日期是 2006-01-01 之后的员工的信息及部门信息
// - 错误示范, 有的员工的 dept_id 为 null
-- select e.*, d.* from emp as e, dept as d where e.entrydate > '2006-01-01' and e.dept_id = d.id;
// - 错误示范, 有的员工的 dept_id 为 null
-- select e.*, d.* from emp as e, dept as d where (e.entrydate, d.id) in (select entrydate, dept_id from emp where entrydate > '2006-01-01');
// - 正确写法
select e.*, d.* from (select * from emp where entrydate > '2006-01-01') as e left join dept as d on e.dept_id ==d.id;
// - 查询员工的姓名、年龄、职位、部门信息。
select e.name, e.age, e.job, d.name from emp as e left join dept as d on e.dept_id = d.id;
// - 查询年龄小于30岁的员工姓名、年龄、职位、部门信息。
select e.name, e.age, e.job, d.name from emp as e left join dept as d on e.dept_id = d.id where age < 30;
select e.name, e.age, e.job, d.name from (select * from emp where age < 30) as e left join dept as d on e.dept_id = d.id;
// - 查询拥有员工的部门ID、部门名称。
// - 外连接, 没有员工的也会被过滤出来
// - select distinct d.id, d.name from dept as d left join emp as e on d.id = e.dept_id;
select distinct d.id, d.name from dept as d join emp as e on d.id = e.dept_id;
// - 查询所有年龄大于40岁的员工,及其归属的部门名称;如果员工没有分配部门,也需要展示出来。
select e.*, d.name from (select * from emp where age > 40) as e left join dept as d on e.dept_id = d.id;
select e.*, d.name from emp as e left join dept as d on e.dept_id = d.id where e.age > 40;
// - 查询所有员工的工资等级。
select e.*, s.grade from emp as e left join salgrade as s on e.salary >= s.losal and e.salary <= s.hisal;
select e.*, s.grade from emp as e , salgrade as s where e.salary >= s.losal and e.salary <= s.hisal;
// - 查询"研发部"所有员工的信息及工资等级。
select e.*, s.grade
from (select * from emp where dept_id = (select id from dept where dept.name = '研发部')) as e,
salgrade as s
where (e.salary >= s.losal and e.salary <= s.hisal)
order by id;
select e.*, s.grade
from (select * from emp where dept_id = (select id from dept where dept.name = '研发部')) as e
left join salgrade as s
on (e.salary >= s.losal and e.salary <= s.hisal)
order by id;
select e.*, s.grade
from emp as e,
salgrade as s
where (e.salary >= s.losal and e.salary <= s.hisal)
and dept_id = (select id from dept where dept.name = '研发部')
order by id;
select *
from emp as e,
salgrade as s,
dept as d
where (e.salary >= s.losal and e.salary <= s.hisal)
and d.name = '研发部'
and e.dept_id == d.id
order by e.id;
// - 查询"研发部"员工的平均工资。
// - 查询工资比"灭绝"高的员工信息。
// - 查询比平均薪资高的员工信息。
// - 查询低于本部门平均工资的员工信息。
// - 查询所有的部门信息,并统计部门的员工人数。
// - 查询所有学生的选课情况,展示出学生名称,学号,课程名称