MySQL练习数据库及完整练习题
数据库创建脚本
1 |
|
测试数据插入脚本
1 |
|
完整练习题及参考答案
基础查询
- 查询所有员工的基本信息(员工ID、姓名、性别、部门名称、职位名称)
1
2
3
4SELECT e.emp_id, e.emp_name, e.gender, d.dept_name, p.position_name
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
JOIN positions p ON e.position_id = p.position_id;
多表关联
- 查询每个部门的名称及其员工人数
1
2
3
4SELECT d.dept_name, COUNT(e.emp_id) AS employee_count
FROM departments d
LEFT JOIN employees e ON d.dept_id = e.dept_id
GROUP BY d.dept_id, d.dept_name;
聚合函数
- 查询每个部门的平均薪资
1
2
3
4
5
6SELECT d.dept_name, AVG(s.amount + s.bonus) AS avg_salary
FROM departments d
JOIN employees e ON d.dept_id = e.dept_id
JOIN salaries s ON e.emp_id = s.emp_id
WHERE s.salary_date = '2023-02-28'
GROUP BY d.dept_id, d.dept_name;
子查询
- 查询薪资高于公司平均薪资的员工
1
2
3
4
5
6
7
8
9SELECT e.emp_name, (s.amount + s.bonus) AS total_salary
FROM employees e
JOIN salaries s ON e.emp_id = s.emp_id
WHERE s.salary_date = '2023-02-28'
AND (s.amount + s.bonus) > (
SELECT AVG(amount + bonus)
FROM salaries
WHERE salary_date = '2023-02-28'
);
复杂查询
查询每个部门薪资最高的员工信息
1
2
3
4
5
6SELECT d.dept_name, e.emp_name, MAX(s.amount + s.bonus) AS max_salary
FROM departments d
JOIN employees e ON d.dept_id = e.dept_id
JOIN salaries s ON e.emp_id = s.emp_id
WHERE s.salary_date = '2023-02-28'
GROUP BY d.dept_id, d.dept_name, e.emp_id, e.emp_name;查询薪资连续两个月增长的员工(修正版)
1
2
3
4
5SELECT e.emp_name
FROM employees e
JOIN salaries s1 ON e.emp_id = s1.emp_id AND s1.salary_date = '2023-01-31'
JOIN salaries s2 ON e.emp_id = s2.emp_id AND s2.salary_date = '2023-02-28'
WHERE (s2.amount + s2.bonus) > (s1.amount + s1.bonus);
高级查询
- 使用CASE WHEN统计各部门不同性别员工人数
1
2
3
4
5
6
7SELECT
d.dept_name,
COUNT(CASE WHEN e.gender = 'M' THEN 1 END) AS male_count,
COUNT(CASE WHEN e.gender = 'F' THEN 1 END) AS female_count
FROM departments d
LEFT JOIN employees e ON d.dept_id = e.dept_id
GROUP BY d.dept_id, d.dept_name;
实用练习题
窗口函数
- 查询每个部门薪资排名前三的员工
MySQL 8.0+
1 |
|
MySQL 5.4
在MySQL 5.4版本中,由于不支持窗口函数(如RANK(), DENSE_RANK(), ROW_NUMBER()),我们需要使用传统方法来实现这个查询。以下是几种可行的解决方案:
方法一:使用用户变量和子查询
1 |
|
方法二:使用自连接和COUNT方式
1 |
|
方法三:使用临时表(更易理解)
1 |
|
方法四:针对每个部门单独查询(简单但效率较低)
1 |
|
注意事项
- 方法一使用了用户变量,在复杂查询中可能不够稳定
- 方法二使用了相关子查询,性能可能较差,特别是数据量大时
- 方法三使用了临时表,是最可靠的方式,但需要额外的存储空间
- 方法四最简单,但需要为每个部门单独执行查询
- 所有方法都假设每个员工在指定月份只有一条薪资记录
日期函数
- 查询入职超过5年的员工
1
2
3SELECT emp_name, hire_date
FROM employees
WHERE hire_date <= DATE_SUB(CURDATE(), INTERVAL 5 YEAR);
可以直接在MySQL 5.4及以上版本运行。
MySQL练习数据库及完整练习题
https://www.305871230.xyz/posts/226496011/