LeetCode题练习与总结:部门工资最高的员工--184

106 篇文章 0 订阅
8 篇文章 0 订阅

一、题目描述

SQL Schema > Pandas Schema > 

表: Employee

+--------------+---------+
| 列名          | 类型    |
+--------------+---------+
| id           | int     |
| name         | varchar |
| salary       | int     |
| departmentId | int     |
+--------------+---------+
在 SQL 中,id是此表的主键。
departmentId 是 Department 表中 id 的外键(在 Pandas 中称为 join key)。
此表的每一行都表示员工的 id、姓名和工资。它还包含他们所在部门的 id。

表: Department

+-------------+---------+
| 列名         | 类型    |
+-------------+---------+
| id          | int     |
| name        | varchar |
+-------------+---------+
在 SQL 中,id 是此表的主键列。
此表的每一行都表示一个部门的 id 及其名称。

查找出每个部门中薪资最高的员工。
按 任意顺序 返回结果表。
查询结果格式如下例所示。

示例 1:

输入:
Employee 表:
+----+-------+--------+--------------+
| id | name  | salary | departmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Jim   | 90000  | 1            |
| 3  | Henry | 80000  | 2            |
| 4  | Sam   | 60000  | 2            |
| 5  | Max   | 90000  | 1            |
+----+-------+--------+--------------+
Department 表:
+----+-------+
| id | name  |
+----+-------+
| 1  | IT    |
| 2  | Sales |
+----+-------+
输出:
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Jim      | 90000  |
| Sales      | Henry    | 80000  |
| IT         | Max      | 90000  |
+------------+----------+--------+
解释:Max 和 Jim 在 IT 部门的工资都是最高的,Henry 在销售部的工资最高。

二、解题思路

  1. 首先,需要连接 Employee 表和 Department 表,以便能够获取每个员工的部门名称。
  2. 然后,需要找到每个部门中薪资最高的员工。这可以通过使用子查询来实现,子查询将为每个部门找到最高薪资。
  3. 最后,需要将子查询的结果与 Employee 表和 Department 表连接起来,以获取最高薪资的员工的名字和部门名称。

三、具体代码

SELECT 
    d.name AS Department,
    e.name AS Employee,
    e.salary AS Salary
FROM 
    Employee e
INNER JOIN Department d ON e.departmentId = d.id
WHERE 
    (e.departmentId, e.salary) IN (
        SELECT 
            departmentId, 
            MAX(salary) 
        FROM 
            Employee 
        GROUP BY 
            departmentId
    );

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 子查询部分:

    • SELECT departmentId, MAX(salary) FROM Employee GROUP BY departmentId
    • 这个子查询首先需要对 Employee 表中的所有记录进行扫描,以找到每个部门的最高薪资。假设 Employee 表中有 n 条记录,则时间复杂度为 O(n)
    • 然后,对结果进行分组,每个部门计算一次最大值。如果 Employee 表中有 d 个不同的部门,则分组操作的时间复杂度为 O(d)
    • 因此,子查询的总体时间复杂度为 O(n + d)
  • 主查询部分:

    • INNER JOIN 操作需要将 Employee 表和 Department 表进行连接。如果 Employee 表有 n 条记录,Department 表有 m 条记录,则最坏情况下的时间复杂度为 O(n * m)。然而,通常情况下,m 远小于 n,并且可以通过索引来优化连接操作,使得实际的时间复杂度接近 O(n)
    • WHERE 子句中的 (e.departmentId, e.salary) IN 操作需要将主查询的结果与子查询的结果进行匹配。由于子查询的结果大小为 d,这个操作的时间复杂度为 O(n * d)

综上所述,整个查询的时间复杂度大致为 O(n + d + n * m + n * d)。如果假设 m 相对于 n 和 d 很小,那么时间复杂度可以简化为 O(n * d)

2. 空间复杂度
  • 子查询部分:

    • 子查询的结果需要存储每个部门的最大薪资,空间复杂度为 O(d)
  • 主查询部分:

    • INNER JOIN 操作可能会生成一个大小为 n 的临时结果集,因为它需要存储连接操作的结果。
    • 最终结果集的大小取决于每个部门有多少个最高薪资的员工。在最坏的情况下,如果每个部门的所有员工都有相同的最高薪资,那么结果集的大小将是 n

因此,整个查询的空间复杂度大致为 O(n + d)

需要注意的是,这些分析是理论上的,实际性能会受到数据库的优化、索引、硬件等因素的影响。实际的时间复杂度和空间复杂度可能会因为这些因素而有所不同。

五、总结知识点

  • SQL查询结构

    • SELECT:用于从数据库中检索数据。
    • FROM:指定查询中涉及的数据表。
    • INNER JOIN:用于将两个或多个表基于相关列进行连接。
    • ON:用于指定 INNER JOIN 的连接条件。
    • WHERE:用于过滤查询结果,基于指定的条件。
  • 别名(Aliases)

    • AS:用于给列或表指定别名,以便在查询结果中更方便地引用。
  • 子查询(Subqueries)

    • 在 WHERE 子句中,子查询用于找到每个部门的最高薪资。
  • 聚合函数(Aggregate Functions)

    • MAX():用于计算某一列中的最大值。
  • 分组(GROUP BY)

    • 用于对结果集进行分组,常与聚合函数一起使用,以计算每个组的数据。
  • 多列比较

    • (e.departmentId, e.salary) IN:用于比较两个列的值是否同时存在于子查询的结果集中。
  • 内连接(INNER JOIN)

    • 用于仅返回两个表中匹配的行。
  • 外键关系

    • Employee.departmentId 是指向 Department.id 的外键,这表明 INNER JOIN 是基于这种外键关系建立的。
  • 查询优化

    • 尽管代码中没有直接体现,但理解查询优化对于编写高效的SQL语句至关重要。例如,对 departmentId 和 salary 列使用索引可以显著提高查询性能。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直学习永不止步

谢谢您的鼓励,我会再接再厉的!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值