多表查询-8-练习总结
多表查询-8-练习总结
- 练习总结
- 练习
- 1. 查询员工的姓名、职位、部门信息
- 2. 查询入职时间大于 5 年的员工姓名、职位、部门信息
- 3. 查询所有员工的部门ID、部门名称
- 4. 查询入职时间大于 5 年的员工, 及其归属的部门名称
- 5. 查询所有员工的部门
- 6. 查询 “技术研发部” 的所有员工信息以及工作地点
- 7. 查询 “技术研发部” 的员工的平均工资
- 8. 查询工资比 “周杰伦” 高的员工信息
- 9. 查询工资比 “平均工资” 高的员工信息
- 10. 查询低于本部门平均工资的员工信息
- 11. 查询所有的部门信息, 并统计部门的员工人数
- 12. 查询所有学生的选课情况, 展示出学生名称, 学号, 课程名称
- 总结
- 多表关系
- 多表查询
练习总结
练习
1. 查询员工的姓名、职位、部门信息
select emp_name, position, dept_name
from emp_info as e,dept_info as d
where e.dept_id = d.dept_id;
从结果上来看是没有问题的, 但是需要注意隐式连接可读性差; 若 emp_info.dept_id
允许 NULL
, 会把这些 NULL
行过滤掉,逻辑等价于 INNER JOIN
, 但代码风格不推荐, 可以尝试进行如下的修改
select e.emp_name, e.position, d.dept_name
from emp_info as ejoin dept_info as d on d.dept_id = e.dept_id;
2. 查询入职时间大于 5 年的员工姓名、职位、部门信息
select emp_name, position, dept_name
from emp_info as ejoin dept_info as d on e.dept_id = d.dept_id
where hire_date < date_sub(curdate(), interval 5 year);
3. 查询所有员工的部门ID、部门名称
select emp_name, d.dept_id, dept_name
from emp_info as e,dept_info as d
where e.dept_id = d.dept_id;
4. 查询入职时间大于 5 年的员工, 及其归属的部门名称
select emp_name, d.dept_id
from emp_info as e,dept_info as d
where e.dept_id = d.dept_idand hire_date < date_sub(curdate(), interval 5 year);
或者使用左外连接
select emp_name, d.dept_name
from emp_info as eleft join dept_info as d on e.dept_id = d.dept_id
where hire_date < date_sub(curdate(), interval 5 year);
当然, 最好的当然还是使用内连接的办法
select emp_name, d.dept_name
from emp_info as ejoin dept_info as d on e.dept_id = d.dept_idand hire_date < date_sub(curdate(), interval 5 year);
5. 查询所有员工的部门
select e.emp_name, d.dept_name
from emp_info as eleft join dept_info as d on d.dept_id = e.dept_id
6. 查询 “技术研发部” 的所有员工信息以及工作地点
select emp_id,emp_name,gender,position,hire_date,salary,location
from emp_info as ejoin dept_info as d on d.dept_id = e.dept_id
7. 查询 “技术研发部” 的员工的平均工资
select avg(salary)
from emp_info as ejoin dept_info d on d.dept_id = e.dept_id
where dept_name = '技术研发部';
8. 查询工资比 “周杰伦” 高的员工信息
select *
from emp_info
where salary > (select salary from emp_info where emp_name = '周杰伦');
9. 查询工资比 “平均工资” 高的员工信息
select *
from emp_info
where salary > (select avg(salary) from emp_info);
10. 查询低于本部门平均工资的员工信息
这题的话, em, 比想象中可能会复杂一点, 子查询的结果应该是部门的id和各个部门的平均工资
select e.*
from emp_info einner join (select dept_id, avg(salary) as avg_salaryfrom emp_infogroup by dept_id) as d on e.dept_id = d.dept_id
where salary < d.avg_salary;
11. 查询所有的部门信息, 并统计部门的员工人数
select d.*, count(*) as `部门的员工人数`
from dept_info as dleft join emp_info as e on e.dept_id = d.dept_id
group by d.dept_id;
12. 查询所有学生的选课情况, 展示出学生名称, 学号, 课程名称
我们之前做了三张表, 一张是学生表students
用于记录学生个人信息, 一张是课程表subjects
用于记录课程的信息, 一张是选课表grades
用于记录学生的选课情况, 如下图所示
select student_name, student_no, subject_name
from (select student_name, student_no, subject_idfrom students as sleft join grades as g on s.student_id = g.student_id) as aleft join subjects as b on a.subject_id = b.subject_id;
这个这个, 这个可能看起来就是比较复杂的一个查询, 所以我下面有一个看起来更为整洁的查询方式, 假设所有学生都有进行选课的话, 可以使用下面这一种方式进行三表连接
SELECT s.student_name,s.student_no,su.subject_name
FROM students AS sJOIN grades AS g ON g.student_id = s.student_idJOIN subjects AS su ON su.subject_id = g.subject_id;
但如果有的学生没有选课但是也需要进行显示的话, 则需要使用下面这种
SELECT s.student_name,s.student_no,su.subject_name
FROM students AS sLEFT JOIN grades AS g ON g.student_id = s.student_idLEFT JOIN subjects AS su ON su.subject_id = g.subject_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, 表B 别名2 WHERE 条件 ...
-
子查询
-
标量子查询
-
列子查询
-
行子查询
-
表子查询
-