面试题答案
一键面试-
查询语句设计
SELECT e.employee_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id JOIN employee_projects ep ON e.employee_id = ep.employee_id JOIN projects p ON ep.project_id = p.project_id GROUP BY e.employee_id, e.employee_name, d.department_name HAVING COUNT(DISTINCT p.project_id) >= 2;
- 首先通过
JOIN
操作将employees
表与departments
表连接,以获取员工所属部门的信息。连接条件是e.department_id = d.department_id
。 - 接着将
employees
表与employee_projects
表连接,连接条件是e.employee_id = ep.employee_id
,这样可以获取员工参与项目的关联信息。 - 然后将
employee_projects
表与projects
表连接,连接条件是ep.project_id = p.project_id
,从而获取项目的详细信息。 - 使用
GROUP BY
子句按照员工ID、员工姓名和部门名称进行分组,这样可以统计每个员工参与的不同项目数量。 - 使用
HAVING COUNT(DISTINCT p.project_id) >= 2
筛选出参与至少两个不同项目的员工。
- 首先通过
-
JOIN连接类型选择及性能分析
- 内连接(INNER JOIN):在本场景下使用内连接是合适的。因为我们只关心有部门归属并且参与了项目的员工信息。内连接会返回满足连接条件的所有行,丢弃不满足连接条件的行。在性能方面,内连接通常是高效的,因为数据库可以通过索引快速定位满足连接条件的行。如果表中数据量较大,且索引设计合理,内连接能够在较短时间内完成连接操作。
- 外连接(LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN):
- LEFT JOIN:如果使用
LEFT JOIN
,假设以employees
表为左表连接其他表,会返回employees
表中的所有行,即使某些员工没有对应的部门信息(departments
表中无匹配行),或者没有参与项目(employee_projects
表和projects
表中无匹配行)。这可能会导致结果集中包含一些我们不关心的数据,并且会增加查询的计算量,因为需要处理这些额外的行。在本场景下不适合使用LEFT JOIN
,除非有特殊需求需要保留所有员工,无论其是否有部门或参与项目。 - RIGHT JOIN:与
LEFT JOIN
类似,RIGHT JOIN
以右表为基准返回所有行。在本场景下同样不适用,因为我们关注的是有实际关联关系(有部门且参与项目)的数据。 - FULL OUTER JOIN:
FULL OUTER JOIN
会返回左右表中所有的行,匹配的行合并,不匹配的行用NULL
填充。这种连接类型会产生大量不必要的数据,并且性能开销极大,在本场景下完全不适用。
- LEFT JOIN:如果使用
综上所述,在本场景下,使用内连接能够在保证结果准确性的同时,达到较好的性能。