掌握SQL连接查询:HR员工数据分析

数据库系列(5部分)
📝 面向新手的DBMS面试题
📝 面向新手的10大SQL查询
掌握SQL基础:(第2部分)
掌握SQL基础:(第1部分)
掌握SQL连接查询:HR员工数据分析
欢迎来到我们的SQL连接查询系列,我们将深入探讨使用连接操作分析HR数据的高级技术。本博客专注于一个员工管理数据库,包含WorkerDepartmentWorker_rating表。我们将提供45个SQL查询,利用各种连接类型(INNER、LEFT等)来处理复杂的HR场景。这些查询非常适合数据分析师HR专业人员开发者,他们希望掌握SQL连接以获得员工洞察。
🧩 数据库架构概览
Worker:存储员工详细信息
列:
worker_id
first_name
last_name
salary
joining_date
department_id
Department:包含部门信息
列:
id
department
Worker_rating:跟踪员工绩效评级
列:
id
worker_id
rating
🏗️ 创建表
  1. CREATE TABLE Department (
  2. id INT PRIMARY KEY AUTO_INCREMENT,
  3. department VARCHAR(50) NOT NULL
  4. );

  5. CREATE TABLE Worker (
  6. worker_id INT PRIMARY KEY AUTO_INCREMENT,
  7. first_name VARCHAR(50) NOT NULL,
  8. last_name VARCHAR(50) NOT NULL,
  9. salary INT NOT NULL,
  10. joining_date DATE NOT NULL,
  11. department_id INT,
  12. FOREIGN KEY (department_id) REFERENCES Department(id)
  13. );

  14. CREATE TABLE Worker_rating (
  15. id INT PRIMARY KEY AUTO_INCREMENT,
  16. worker_id INT,
  17. rating INT NOT NULL,
  18. FOREIGN KEY (worker_id) REFERENCES Worker(worker_id)
  19. );
sql
📝 插入示例数据
  1. INSERT INTO Department (id, department) VALUES
  2. (1, 'HR'),
  3. (2, 'Admin'),
  4. (3, 'Account'),
  5. (4, 'Sales');

  6. INSERT INTO Worker (worker_id, first_name, last_name, salary, joining_date, department_id) VALUES
  7. (1, 'Monika', 'Arora', 100000, '1982-02-20', 1),
  8. (2, 'Niharika', 'Verma', 80000, '2014-06-11', 2),
  9. (3, 'Vishal', 'Singhal', 300000, '2015-02-20', 1),
  10. (4, 'Amitabh', 'Singh', 500000, '2014-02-20', 2),
  11. (5, 'Vivek', 'Bhati', 500000, '2016-06-11', 2),
  12. (6, 'Vipul', 'Diwan', 200000, '2014-06-11', 3),
  13. (7, 'Satish', 'Kumar', 75000, '1985-01-20', 4),
  14. (8, 'Geetika', 'Chauhan', 90000, '1988-04-11', 2),
  15. (9, 'Ramesh', 'Sharma', 120000, '2018-03-15', 1),
  16. (10, 'Suresh', 'Yadav', 95000, '2017-07-01', 3),
  17. (11, 'Anjali', 'Kapoor', 85000, '2013-01-25', 4),
  18. (12, 'Pooja', 'Malhotra', 110000, '2016-12-10', 2),
  19. (13, 'Deepak', 'Gupta', 140000, '2019-09-05', 1),
  20. (14, 'Rohit', 'Jain', 70000, '2020-01-20', 3),
  21. (15, 'Sneha', 'Mehra', 80000, '2012-06-25', 4),
  22. (16, 'Arjun', 'Chopra', 130000, '2021-03-14', 1),
  23. (17, 'Kiran', 'Reddy', 120000, '2022-05-18', 2),
  24. (18, 'Meena', 'Naik', 110000, '2020-08-21', 1),
  25. (19, 'Rajesh', 'Pillai', 95000, '2018-11-30', 4),
  26. (20, 'Bhavna', 'Iyer', 105000, '2015-07-22', 3),
  27. (21, 'Prakash', 'Joshi', 98000, '2016-04-25', 2),
  28. (22, 'Gaurav', 'Patel', 88000, '2019-10-15', 3),
  29. (23, 'Manisha', 'Desai', 102000, '2014-11-20', 2),
  30. (24, 'Ajay', 'Khan', 92000, '2021-01-12', 4),
  31. (25, 'Sanjay', 'Ghosh', 135000, '2017-03-08', 1),
  32. (26, 'Priya', 'Das', 80000, '2018-05-14', 2),
  33. (27, 'Anil', 'Nair', 125000, '2020-09-16', 3),
  34. (28, 'Siddharth', 'Rao', 140000, '2022-11-10', 4),
  35. (29, 'Radha', 'Kulkarni', 95000, '2015-12-23', 2),
  36. (30, 'Tanya', 'Mishra', 89000, '2019-06-29', 3);

  37. INSERT INTO Worker_rating (id, worker_id, rating) VALUES
  38. (1, 1, 3),
  39. (2, 1, 2),
  40. (3, 2, 4),
  41. (4, 3, 5),
  42. (5, 4, 2),
  43. (6, 2, 1),
  44. (7, 3, 3),
  45. (8, 5, 2),
  46. (9, 6, 5),
  47. (10, 7, 4),
  48. (11, 8, 3),
  49. (12, 9, 4),
  50. (13, 10, 3),
  51. (14, 11, 4),
  52. (15, 12, 2),
  53. (16, 13, 5),
  54. (17, 14, 3),
  55. (18, 15, 4),
  56. (19, 16, 5),
  57. (20, 17, 2),
  58. (21, 18, 3),
  59. (22, 19, 4),
  60. (23, 20, 5),
  61. (24, 21, 2),
  62. (25, 22, 4),
  63. (26, 23, 3),
  64. (27, 24, 2),
  65. (28, 25, 5),
  66. (29, 26, 3),
  67. (30, 27, 4);
sql
🔍 员工分析的高级SQL连接查询
以下是45个SQL查询及其解释,利用连接操作来组合WorkerDepartmentWorker_rating表的数据,以获得可操作的HR洞察。
1. 检索所有员工的名字和姓氏以及他们的部门名称
  1. SELECT w.first_name, w.last_name, d.department
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id;
sql
2. 检索每个部门员工的总工资
  1. SELECT d.department, SUM(w.salary) AS total_salary
  2. FROM Department d
  3. JOIN Worker w ON d.id = w.department_id
  4. GROUP BY d.department;
sql
3. 获取按部门分组的员工数量
  1. SELECT d.department, COUNT(w.worker_id) AS number_of_workers
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. GROUP BY d.department
  5. HAVING AVG(w.salary) > 100000;
sql
4. 获取每个部门的最高工资记录
  1. SELECT d.department, MAX(w.salary) AS highest_salary
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. GROUP BY d.department;
sql
5. 获取评级大于等于4的员工的平均评级和详细信息
  1. SELECT w.first_name, w.last_name, w.salary, AVG(r.rating) AS average_rating
  2. FROM Worker w
  3. JOIN Worker_rating r ON w.worker_id = r.worker_id
  4. WHERE r.rating >= 4
  5. GROUP BY w.worker_id, w.first_name, w.last_name, w.salary;
sql
6. 获取评级为3或以上的员工列表,包括部门名称和工资
  1. SELECT w.first_name, w.last_name, d.department, w.salary
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating >= 3;
sql
7. 显示评级为4或以上的员工按部门分组的平均工资
  1. SELECT d.department, AVG(w.salary) AS average_salary
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating >= 4
  6. GROUP BY d.department;
sql
8. 查找每个部门中工资最高的员工
  1. SELECT w.first_name, w.last_name, d.department, w.salary
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. WHERE w.salary = (
  5. SELECT MAX(salary)
  6. FROM Worker w2
  7. WHERE w2.department_id = w.department_id
  8. );
sql
9. 获取每个部门的员工数量和平均工资
  1. SELECT d.department, COUNT(w.worker_id) AS worker_count, AVG(w.salary) AS avg_salary
  2. FROM Department d
  3. LEFT JOIN Worker w ON d.id = w.department_id
  4. GROUP BY d.department;
sql
10. 查找评级为5的员工及其部门信息
  1. SELECT w.first_name, w.last_name, d.department, r.rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating = 5;
sql
11. 获取每个部门的最高和最低工资
  1. SELECT d.department, MAX(w.salary) AS max_salary, MIN(w.salary) AS min_salary
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. GROUP BY d.department;
sql
12. 查找平均评级最高的部门
  1. SELECT d.department, AVG(r.rating) AS avg_rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. GROUP BY d.department
  6. ORDER BY avg_rating DESC
  7. LIMIT 1;
sql
13. 获取工资高于部门平均工资的员工
  1. SELECT w.first_name, w.last_name, w.salary, d.department
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. WHERE w.salary > (
  5. SELECT AVG(salary)
  6. FROM Worker w2
  7. WHERE w2.department_id = w.department_id
  8. );
sql
14. 查找每个部门中评级最高的员工
  1. SELECT w.first_name, w.last_name, d.department, r.rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating = (
  6. SELECT MAX(rating)
  7. FROM Worker_rating r2
  8. JOIN Worker w2 ON r2.worker_id = w2.worker_id
  9. WHERE w2.department_id = w.department_id
  10. );
sql
15. 获取每个部门的工资分布(高、中、低)
  1. SELECT d.department,
  2. COUNT(CASE WHEN w.salary >= 100000 THEN 1 END) AS high_salary,
  3. COUNT(CASE WHEN w.salary BETWEEN 50000 AND 99999 THEN 1 END) AS medium_salary,
  4. COUNT(CASE WHEN w.salary < 50000 THEN 1 END) AS low_salary
  5. FROM Worker w
  6. JOIN Department d ON w.department_id = d.id
  7. GROUP BY d.department;
sql
16. 查找评级低于3的员工及其部门
  1. SELECT w.first_name, w.last_name, d.department, r.rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating < 3;
sql
17. 获取每个部门的工资总和和员工数量
  1. SELECT d.department, SUM(w.salary) AS total_salary, COUNT(w.worker_id) AS worker_count
  2. FROM Department d
  3. LEFT JOIN Worker w ON d.id = w.department_id
  4. GROUP BY d.department;
sql
18. 查找评级为1的员工及其部门信息
  1. SELECT w.first_name, w.last_name, d.department, r.rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating = 1;
sql
19. 获取每个部门的平均评级
  1. SELECT d.department, AVG(r.rating) AS average_rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. GROUP BY d.department;
sql
20. 查找工资最高的前5名员工及其部门
  1. SELECT w.first_name, w.last_name, d.department, w.salary
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. ORDER BY w.salary DESC
  5. LIMIT 5;
sql
21. 获取评级为4或5的员工数量按部门分组
  1. SELECT d.department, COUNT(w.worker_id) AS high_rated_workers
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating IN (4, 5)
  6. GROUP BY d.department;
sql
22. 查找每个部门中评级最低的员工
  1. SELECT w.first_name, w.last_name, d.department, r.rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating = (
  6. SELECT MIN(rating)
  7. FROM Worker_rating r2
  8. JOIN Worker w2 ON r2.worker_id = w2.worker_id
  9. WHERE w2.department_id = w.department_id
  10. );
sql
23. 获取每个部门的工资范围
  1. SELECT d.department,
  2. MAX(w.salary) - MIN(w.salary) AS salary_range,
  3. MAX(w.salary) AS max_salary,
  4. MIN(w.salary) AS min_salary
  5. FROM Worker w
  6. JOIN Department d ON w.department_id = d.id
  7. GROUP BY d.department;
sql
24. 查找评级为2的员工及其部门信息
  1. SELECT w.first_name, w.last_name, d.department, r.rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating = 2;
sql
25. 获取每个部门的平均工资和平均评级
  1. SELECT d.department, AVG(w.salary) AS avg_salary, AVG(r.rating) AS avg_rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. GROUP BY d.department;
sql
26. 查找评级为3的员工及其部门信息
  1. SELECT w.first_name, w.last_name, d.department, r.rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating = 3;
sql
27. 获取每个部门的工资中位数
  1. SELECT d.department,
  2. AVG(w.salary) AS median_salary
  3. FROM Worker w
  4. JOIN Department d ON w.department_id = d.id
  5. WHERE w.salary IN (
  6. SELECT w2.salary
  7. FROM Worker w2
  8. WHERE w2.department_id = w.department_id
  9. ORDER BY w2.salary
  10. LIMIT 1 OFFSET (
  11. SELECT COUNT(*) / 2
  12. FROM Worker w3
  13. WHERE w3.department_id = w.department_id
  14. )
  15. )
  16. GROUP BY d.department;
sql
28. 查找评级为4的员工及其部门信息
  1. SELECT w.first_name, w.last_name, d.department, r.rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating = 4;
sql
29. 获取每个部门的工资标准差
  1. SELECT d.department,
  2. STDDEV(w.salary) AS salary_stddev
  3. FROM Worker w
  4. JOIN Department d ON w.department_id = d.id
  5. GROUP BY d.department;
sql
30. 查找评级为5的员工及其部门信息
  1. SELECT w.first_name, w.last_name, d.department, r.rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating = 5;
sql
31. 获取每个部门的工资分布百分比
  1. SELECT d.department,
  2. ROUND(COUNT(CASE WHEN w.salary >= 100000 THEN 1 END) * 100.0 / COUNT(*), 2) AS high_salary_percent,
  3. ROUND(COUNT(CASE WHEN w.salary BETWEEN 50000 AND 99999 THEN 1 END) * 100.0 / COUNT(*), 2) AS medium_salary_percent,
  4. ROUND(COUNT(CASE WHEN w.salary < 50000 THEN 1 END) * 100.0 / COUNT(*), 2) AS low_salary_percent
  5. FROM Worker w
  6. JOIN Department d ON w.department_id = d.id
  7. GROUP BY d.department;
sql
32. 查找评级分布按部门分组
  1. SELECT d.department,
  2. COUNT(CASE WHEN r.rating = 1 THEN 1 END) AS rating_1,
  3. COUNT(CASE WHEN r.rating = 2 THEN 1 END) AS rating_2,
  4. COUNT(CASE WHEN r.rating = 3 THEN 1 END) AS rating_3,
  5. COUNT(CASE WHEN r.rating = 4 THEN 1 END) AS rating_4,
  6. COUNT(CASE WHEN r.rating = 5 THEN 1 END) AS rating_5
  7. FROM Worker w
  8. JOIN Department d ON w.department_id = d.id
  9. JOIN Worker_rating r ON w.worker_id = r.worker_id
  10. GROUP BY d.department;
sql
33. 列出最高工资大于300,000的部门
  1. SELECT d.department
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. GROUP BY d.department
  5. HAVING MAX(w.salary) > 300000;
sql
34. 显示员工平均评级恰好为2的部门
  1. SELECT d.department
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. GROUP BY d.department
  6. HAVING AVG(r.rating) = 2;
sql
35. 获取平均评级小于3且总工资大于1,000,000的部门
  1. SELECT d.department
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. GROUP BY d.department
  6. HAVING AVG(r.rating) < 3 AND SUM(w.salary) > 1000000;
sql
36. 检索评级为1或2的员工及其部门名称
  1. SELECT w.first_name, w.last_name, d.department
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. WHERE r.rating = 1 OR r.rating = 2;
sql
37. 查找总工资最高的部门
  1. SELECT d.department, SUM(w.salary) AS total_salary
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. GROUP BY d.department
  5. ORDER BY total_salary DESC
  6. LIMIT 1;
sql
38. 查找平均评级最低的部门,排除没有评级的部门
  1. SELECT d.department, AVG(r.rating) AS average_rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. GROUP BY d.department
  6. ORDER BY average_rating ASC
  7. LIMIT 1;
sql
39. 查找总工资大于500,000的部门的总工资和平均评级
  1. SELECT d.department, SUM(w.salary) AS total_salary, AVG(r.rating) AS average_rating
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. JOIN Worker_rating r ON w.worker_id = r.worker_id
  5. GROUP BY d.department
  6. HAVING SUM(w.salary) > 500000;
sql
40. 使用GROUP_CONCAT获取按部门分组的员工姓名
  1. SELECT d.department, GROUP_CONCAT(CONCAT(w.first_name, ' ', w.last_name)) AS worker_names
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. GROUP BY d.department;
sql
41. 获取过去5年加入的员工
  1. SELECT w.first_name, w.last_name, w.joining_date
  2. FROM Worker w
  3. WHERE w.joining_date >= DATE_SUB(CURDATE(), INTERVAL 5 YEAR);
sql
42. 获取每年加入的员工数量
  1. SELECT YEAR(w.joining_date) AS join_year, COUNT(w.worker_id) AS worker_count
  2. FROM Worker w
  3. GROUP BY YEAR(w.joining_date);
sql
43. 获取每个部门的最早和最晚加入日期
  1. SELECT d.department, MIN(w.joining_date) AS earliest_joining, MAX(w.joining_date) AS latest_joining
  2. FROM Worker w
  3. JOIN Department d ON w.department_id = d.id
  4. GROUP BY d.department;
sql
44. 获取在公司工作超过10年的员工
  1. SELECT w.first_name, w.last_name, w.joining_date
  2. FROM Worker w
  3. WHERE w.joining_date < DATE_SUB(CURDATE(), INTERVAL 10 YEAR);
sql
45. 检索今天加入的员工
  1. SELECT w.first_name, w.last_name, w.joining_date
  2. FROM Worker w
  3. WHERE DATE(w.joining_date) = CURDATE();
sql
🎉 结论
本博客演示了45个SQL查询,利用连接操作从员工数据库中提取可操作的HR洞察。从分析工资和评级到跟踪加入日期,这些查询展示了SQL连接在员工管理中的强大功能。练习这些示例以增强你的HR数据分析能力,并通过高效的基于连接的查询推动明智的决策。
关键词:SQL、数据库管理系统、数据库、教程、连接查询、HR分析