一. 列出所有员工的姓名及其直接上级的姓名
sql
SELECT
e.emp_name AS 员工姓名,
m.emp_name AS 直接上级姓名
FROM employees e
LEFT JOIN employees m
ON e.mgr_id = m.emp_id; -- 员工的上级编号 = 上级的员工编号
-- 说明:用 LEFT JOIN 保留无上级的员工(上级姓名为 NULL),若只需有上级的员工,改用 INNER JOIN
2. 列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称
sql
SELECT
e.emp_id AS 员工编号,
e.emp_name AS 员工姓名,
d.dept_name AS 部门名称
FROM employees e
INNER JOIN employees m
ON e.mgr_id = m.emp_id -- 关联上级
INNER JOIN departments d
ON e.dept_id = d.dept_id -- 关联部门
WHERE e.hire_date < m.hire_date; -- 员工入职日期 < 上级入职日期
3. 列出部门名称和这些部门的员工信息,同时列出没有员工的部门
sql
SELECT
d.dept_name AS 部门名称,
e.* AS 员工信息 -- 若需指定字段,替换为 e.emp_id, e.emp_name...
FROM departments d
LEFT JOIN employees e
ON d.dept_id = e.dept_id;
-- 说明:无员工的部门,员工信息字段会显示 NULL
4. 列出在财务部工作的员工的姓名(不知道部门编号)
sql
SELECT e.emp_name AS 财务部员工姓名
FROM employees e
INNER JOIN departments d
ON e.dept_id = d.dept_id
WHERE d.dept_name = '财务部'; -- 按部门名称过滤
5. 列出薪金高于公司平均薪金的所有员工信息、所在部门名称、上级领导
sql
SELECT
e.*, -- 员工详细信息
d.dept_name AS 部门名称,
m.emp_name AS 上级领导姓名
FROM employees e
INNER JOIN departments d
ON e.dept_id = d.dept_id
LEFT JOIN employees m
ON e.mgr_id = m.emp_id
WHERE e.salary > (SELECT AVG(salary) FROM employees); -- 工资 > 公司平均工资
6. 列出与陈超从事相同工作的所有员工及部门名称
sql
SELECT
e.emp_name AS 员工姓名,
d.dept_name AS 部门名称
FROM employees e
INNER JOIN departments d
ON e.dept_id = d.dept_id
WHERE
e.job = (SELECT job FROM employees WHERE emp_name = '陈超') -- 与陈超职位相同
AND e.emp_name != '陈超'; -- 排除陈超本人
-- 若有重名(emp_name='陈超'多人),改用 IN:
-- WHERE e.job IN (SELECT job FROM employees WHERE emp_name = '陈超') AND e.emp_name != '陈超'
7. 查出至少有一个员工的部门,显示部门编号、名称、位置、人数
sql
SELECT
d.dept_id AS 部门编号,
d.dept_name AS 部门名称,
d.location AS 部门位置,
COUNT(e.emp_id) AS 部门人数
FROM departments d
INNER JOIN employees e
ON d.dept_id = e.dept_id
GROUP BY d.dept_id, d.dept_name, d.location -- 分组字段包含部门所有非聚合字段
HAVING COUNT(e.emp_id) >= 1; -- 至少1个员工
-- 简化:INNER JOIN 本身已过滤无员工的部门,HAVING 可省略,但保留更清晰
8. 列出薪金高于财务部员工平均薪金的员工姓名、薪金、部门名称
sql
SELECT
e.emp_name AS 员工姓名,
e.salary AS 薪金,
d.dept_name AS 部门名称
FROM employees e
INNER JOIN departments d
ON e.dept_id = d.dept_id
WHERE
e.salary > (
-- 子查询:计算财务部员工平均工资
SELECT AVG(salary)
FROM employees
INNER JOIN departments
ON employees.dept_id = departments.dept_id
WHERE departments.dept_name = '财务部'
);
二
1. 查询部门编号为 D2019060011 的所有员工
sql
SELECT *
FROM employees
WHERE dept_id = 'D2019060011';
2. 所有财务总监的姓名、编号和部门编号
sql
SELECT emp_name, emp_id, dept_id
FROM employees
WHERE job = '财务总监';
3. 找出奖金高于工资的员工
sql
-- 注意:需处理 bonus 为 NULL 的情况(NULL 不满足 > 条件)
SELECT *
FROM employees
WHERE bonus > salary
AND bonus IS NOT NULL;
4. 找出奖金高于工资 40% 的员工
sql
SELECT *
FROM employees
WHERE bonus > salary * 0.4
AND bonus IS NOT NULL;
5. 部门 D2019090011 的财务总监 + 部门 D2019060011 的财务专员(详细资料)
sql
SELECT *
FROM employees
WHERE (dept_id = 'D2019090011' AND job = '财务总监')
OR (dept_id = 'D2019060011' AND job = '财务专员');
6. 多条件组合查询(详细资料)
sql
SELECT *
FROM employees
WHERE (dept_id = 'D2019090001' AND job = '总经理')
OR (dept_id = 'D2019090011' AND job = '财务总监')
OR (job NOT IN ('总经理', '销售总监') AND salary >= 4000);
7. 有奖金的工种(去重)
sql
SELECT DISTINCT job
FROM employees
WHERE bonus IS NOT NULL
AND bonus > 0; -- 假设奖金为0视为无奖金
8. 无奖金或奖金低于 1000 的员工
sql
SELECT *
FROM employees
WHERE bonus IS NULL
OR bonus < 1000;
9. 查询名字由两个字组成的员工(中文姓名)
sql
-- MySQL 中用 LENGTH() 取字节数(中文1字=3字节),CHAR_LENGTH() 取字符数
SELECT *
FROM employees
WHERE CHAR_LENGTH(emp_name) = 2;
-- 若数据库编码为 GBK(中文1字=2字节),可用:
-- SELECT * FROM employees WHERE LENGTH(emp_name) = 4;
10. 查询 2020 年入职的员工
sql
-- 方法1:用 YEAR() 函数提取年份
SELECT *
FROM employees
WHERE YEAR(hire_date) = 2020;
-- 方法2:用日期范围(性能更优,支持索引)
SELECT *
FROM employees
WHERE hire_date BETWEEN '2020-01-01' AND '2020-12-31 23:59:59';
11. 所有员工详细信息(按编号升序排序)
sql
SELECT *
FROM employees
ORDER BY emp_id ASC; -- ASC 可省略(默认升序)
12. 所有员工详细信息(工资降序,工资相同则入职日期升序)
sql
SELECT *
FROM employees
ORDER BY salary DESC, hire_date ASC;
13. 每个部门的平均工资
sql
SELECT dept_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id; -- 按部门分组
14. 每个部门的雇员数量
sql
SELECT dept_id, COUNT(emp_id) AS emp_count
FROM employees
GROUP BY dept_id;
-- 若需统计包含 NULL 员工(如无编号),用 COUNT(*):
-- SELECT dept_id, COUNT(*) AS emp_count FROM employees GROUP BY dept_id;
15. 每种工作的最高工资、最低工资、人数
sql
SELECT
job,
MAX(salary) AS max_salary,
MIN(salary) AS min_salary,
COUNT(emp_id) AS emp_count
FROM employees
GROUP BY job;
16. 最低薪金大于 4000 的工作及员工人数
sql
-- 先用 GROUP BY 分组计算最低工资,再用 HAVING 过滤分组结果(WHERE 不能过滤聚合结果)
SELECT
job,
COUNT(emp_id) AS emp_count
FROM employees
GROUP BY job
HAVING MIN(salary) > 4000;
17. 各部门工资总和(合计 > 6000,按总和升序)
sql
SELECT
dept_id,
SUM(salary) AS total_salary
FROM employees
GROUP BY dept_id
HAVING SUM(salary) > 6000 -- 过滤工资总和>6000的部门
ORDER BY total_salary ASC; -- 按总和升序排列