Leetcode的MySQL中等练习

文章目录

  • 176. 第二高的薪水
    • 个人解题思路
  • 178. 分数排名
    • 个人解题思路
  • 184. 部门工资最高的员工
    • 个人解题思路
  • 570. 至少有5名直接下属的经理
    • 个人解题思路
  • 602. 好友申请 II :谁有最多的好友
    • 个人解题思路
  • 608. 树节点
    • 个人解题思路
  • 626. 换座位
    • 个人解题思路
  • 1045. 买下所有产品的客户
    • 个人解题思路
  • 1070. 产品销售分析 III
    • 个人解题思路

176. 第二高的薪水

本题链接

个人解题思路

  1. 方案一

    • 首先查询并返回表内最大的薪水,第二高的薪水要比返回的最高薪水低,将这个的条件写在where语句后
    • 再查询当前表内的最大的薪水,此时返回的是表内第二大薪水,因为在where语句已过滤了最大的薪水
  • 代码实现
select max(salary) as SecondHighestSalary 
from Employee
where salary < (select max(salary) from Employee)
  1. 方案二

    • 首先想到流程控制函数的ifnull(value1,value2),不为null返回value1,为null则返回value2
    • 不为null就返回第二高的薪水,这里要用到降序,再用分页思想选择第二,
    • 为null就直接返回null
    • 最后给表改个名
  • 代码实现
select IFNULL((select distinct salary 
             from Employee
             order by salary desc
             limit 1,1),NULL)
as SecondHighestSalary

还有一种写法可以运行,但是好像没这种写法,但我还是记录一下,也是先找出表内最大的薪水,再找一个薪水,此时最大的薪水不在这个表内了,所以就是在剩下的薪水内再找最大的薪水,感觉这也算是找到了第二高的薪水吧

  • 代码实现
select max(salary) as SecondHighestSalary 
from Employee
where salary not in (select max(salary) from Employee)
  • 测试结果
    Leetcode的MySQL中等练习_第1张图片
    Leetcode的MySQL中等练习_第2张图片

178. 分数排名

本题链接

个人解题思路

  1. 首先题目要求我们对分数进行排序,且有自己的排序规则,这里可以使用DENSE_RANK函数,该函数是一个窗口函数,它会为分区或结果集中的每一行分配排名,且排名没有间隙
  2. 使用DENSE_RANK() 进行排名会得到:1,1,2,3,4,4,5,以此类推
  3. 使用 RANK() 进行排名会得到:1,1,3,4,5,5,7,以此类推
  4. 使用 ROW_NUMBER() 进行排名会得到:1,2,3,4,5,6,以此类推
  5. 要对成绩先进行一个降序处理order by score desc
  6. 再使用DENSE_RANK函数对降序后的成绩进行排名,并且对排名的字段进行命名rank与题中示例结果保持一致
  • 代码实现
select score,
dense_rank() over (order by score desc) as 'rank'
from Scores
  • 测试结果

Leetcode的MySQL中等练习_第3张图片

184. 部门工资最高的员工

本题链接

个人解题思路

  1. 首先在Employee表中根据departmentId分组查询,不同组下薪水的最大值
  2. 再根据departmentId链接Department 表,根据departmentId和salary查找相对应部门的名字
  3. 最后返回每个部门中薪资最高的员工
  • 代码实现
select d.name as Department ,e.name as Employee ,salary as Salary 
from Employee e inner join Department d
on d.id=e.departmentId
where (e.departmentId,e.salary )in
            (select departmentId ,max(salary) salary
             from Employee 
             group by departmentId);
  • 测试结果
    Leetcode的MySQL中等练习_第4张图片

570. 至少有5名直接下属的经理

本题链接

个人解题思路

  1. 典型自我引用,这里我将Employee表写了两次,分别为a表b表,使用a表内连接b表,条件是id等于经理id,这样就能找到被引用的
  2. 再将经理id分组查询
  3. 分好组后有大于等于5个经理id数量的就说明这五个人都被同一个经理管着,因为是按照经理id分类的,managerId 大于等于5的时候就说明这个managerId下面有至少五个员工
  4. 注意这里不需要去重,经理名字都相同也不是不可能
  • 代码实现
select a.name
from Employee a inner join Employee b
on a.id = b.managerId
group by b.managerId
having count(b.managerId)>=5 
  • 测试结果
    Leetcode的MySQL中等练习_第5张图片

602. 好友申请 II :谁有最多的好友

本题链接

个人解题思路

  1. 首先要明确一件事,添加好友成功后获得好友这件事是双向的,a申请添加b的好友,b同意了,那么a就会多了b这个好友,同样的,b也会多了a这个好友
  2. 明确了这个前提我们很容易就能知道拥有好友的个数就是表内的requester_id 、accepter_id 出现的次数
  3. 使用union all 合并查询的结果并且不去重,这样就能知道到底有多少数目
  4. 再根据id进行分组,分组后统计id数量,进行降序排列,使用分页思想取最上面一行
  5. 这样我们就能找出拥有最多的好友的人和他拥有的好友数目
  • 代码实现
select id,count(id) as num
from (  select requester_id as id from RequestAccepted
        union all
        select accepter_id from RequestAccepted ) a
group by id 
order by num desc
limit 0,1
  • 测试结果
    Leetcode的MySQL中等练习_第6张图片

608. 树节点

本题链接

个人解题思路

  1. 由于结果有三种情况且是同时进行的,考虑用case when 条件一 then 结果一 when 条件二 结果二 …… end根据p_id的不同情况返回不同的类型
  2. p_id为null时没有父节点,那么它就是一个根节点,返回 root
  3. 再对表中的p_id进行查询,若id存在于p_id的查询结果中,那么说明这个节点肯定是另一个节点的父节点,返回inner
  4. 若以上两种情况均不满足,那么这个节点就是一个叶子节点返回leaf
  5. 在查询输出的时候要输出在type字段下,记得重命名
  • 代码实现
select id,case  when p_id is null then 'Root'
                when id in (select p_id from tree) then "Inner"
                else 'Leaf' 
                end as type
from Tree
  • 测试结果
    Leetcode的MySQL中等练习_第7张图片

626. 换座位

本题链接

个人解题思路

  1. 奇数偶数问题可以用取模解决,mod(),将id取模2,1则是奇数,0则是偶数
  2. 当这个id取模后为1并且这个id等于所有id数量,那么这就是最后一个奇数,就在原位不交换
  3. 1是奇数时让id+1,这样就能变成下一个数
  4. 0是偶数时让id-1,往前进一位,这样连续的两个数id至此就进行了交换
  5. 最后要按照id的升序来返回结果表
  • 代码实现
select case when mod(id,2) = 1 and id = (select count(*)from seat) then id
            when mod(id,2) = 1 then id+1
            when mod(id,2) = 0 then id-1
            end as id,student
from Seat
order by id asc
  • 测试结果
    Leetcode的MySQL中等练习_第8张图片

1045. 买下所有产品的客户

本题链接

个人解题思路

  1. 先根据customer_id分组,这样就能知道一个顾客买了多少产品
  2. 在此基础上再条件过滤,当顾客购买的产品数量和Product 表内产品数量相等时,就视为该顾客就购买了所有的产品
  3. 顾客购买的产品数量要去重,可能会购买同个产品多次
  • 代码实现
select customer_id 
from Customer
group by customer_id
having count(distinct product_key)=(select count(*) from Product)
  • 测试结果
    Leetcode的MySQL中等练习_第9张图片

1070. 产品销售分析 III

本题链接

个人解题思路

  1. 先根据product_id进行分组查询,查询product_id和其对应的最小年份
  2. 再在条件过滤语句中写在上述条件内的product_id,year
  • 代码实现
select product_id ,year as first_year ,quantity ,price 
from Sales
where (product_id,year) in (select product_id,min(year) 
                            from Sales 
                            group by product_id);
  • 测试结果
    Leetcode的MySQL中等练习_第10张图片

你可能感兴趣的:(力扣,leetcode,mysql,算法)