文章目录
176. 第二高的薪水个人解题思路
178. 分数排名个人解题思路
184. 部门工资最高的员工个人解题思路
570. 至少有5名直接下属的经理个人解题思路
602. 好友申请 II :谁有最多的好友个人解题思路
608. 树节点个人解题思路
626. 换座位个人解题思路
1045. 买下所有产品的客户个人解题思路
1070. 产品销售分析 III个人解题思路
176. 第二高的薪水
本题链接
个人解题思路
方案一
首先查询并返回表内最大的薪水,第二高的薪水要比返回的最高薪水低,将这个的条件写在where语句后再查询当前表内的最大的薪水,此时返回的是表内第二大薪水,因为在where语句已过滤了最大的薪水
代码实现
select max(salary) as SecondHighestSalary
from Employee
where salary < (select max(salary) from Employee)
方案二
首先想到流程控制函数的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)
测试结果
178. 分数排名
本题链接
个人解题思路
首先题目要求我们对分数进行排序,且有自己的排序规则,这里可以使用DENSE_RANK函数,该函数是一个窗口函数,它会为分区或结果集中的每一行分配排名,且排名没有间隙使用DENSE_RANK() 进行排名会得到:1,1,2,3,4,4,5,以此类推使用 RANK() 进行排名会得到:1,1,3,4,5,5,7,以此类推使用 ROW_NUMBER() 进行排名会得到:1,2,3,4,5,6,以此类推要对成绩先进行一个降序处理order by score desc再使用DENSE_RANK函数对降序后的成绩进行排名,并且对排名的字段进行命名rank与题中示例结果保持一致
代码实现
select score,
dense_rank() over (order by score desc) as 'rank'
from Scores
测试结果
184. 部门工资最高的员工
本题链接
个人解题思路
首先在Employee表中根据departmentId分组查询,不同组下薪水的最大值再根据departmentId链接Department 表,根据departmentId和salary查找相对应部门的名字最后返回每个部门中薪资最高的员工
代码实现
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);
测试结果
570. 至少有5名直接下属的经理
本题链接
个人解题思路
典型自我引用,这里我将Employee表写了两次,分别为a表b表,使用a表内连接b表,条件是id等于经理id,这样就能找到被引用的再将经理id分组查询分好组后有大于等于5个经理id数量的就说明这五个人都被同一个经理管着,因为是按照经理id分类的,managerId 大于等于5的时候就说明这个managerId下面有至少五个员工注意这里不需要去重,经理名字都相同也不是不可能
代码实现
select a.name
from Employee a inner join Employee b
on a.id = b.managerId
group by b.managerId
having count(b.managerId)>=5
测试结果
602. 好友申请 II :谁有最多的好友
本题链接
个人解题思路
首先要明确一件事,添加好友成功后获得好友这件事是双向的,a申请添加b的好友,b同意了,那么a就会多了b这个好友,同样的,b也会多了a这个好友明确了这个前提我们很容易就能知道拥有好友的个数就是表内的requester_id 、accepter_id 出现的次数使用union all 合并查询的结果并且不去重,这样就能知道到底有多少数目再根据id进行分组,分组后统计id数量,进行降序排列,使用分页思想取最上面一行这样我们就能找出拥有最多的好友的人和他拥有的好友数目
代码实现
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
测试结果
608. 树节点
本题链接
个人解题思路
由于结果有三种情况且是同时进行的,考虑用case when 条件一 then 结果一 when 条件二 结果二 …… end根据p_id的不同情况返回不同的类型当p_id为null时没有父节点,那么它就是一个根节点,返回 root再对表中的p_id进行查询,若id存在于p_id的查询结果中,那么说明这个节点肯定是另一个节点的父节点,返回inner若以上两种情况均不满足,那么这个节点就是一个叶子节点返回leaf在查询输出的时候要输出在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
测试结果
626. 换座位
本题链接
个人解题思路
奇数偶数问题可以用取模解决,mod(),将id取模2,1则是奇数,0则是偶数当这个id取模后为1并且这个id等于所有id数量,那么这就是最后一个奇数,就在原位不交换1是奇数时让id+1,这样就能变成下一个数0是偶数时让id-1,往前进一位,这样连续的两个数id至此就进行了交换最后要按照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
测试结果
1045. 买下所有产品的客户
本题链接
个人解题思路
先根据customer_id分组,这样就能知道一个顾客买了多少产品在此基础上再条件过滤,当顾客购买的产品数量和Product 表内产品数量相等时,就视为该顾客就购买了所有的产品顾客购买的产品数量要去重,可能会购买同个产品多次
代码实现
select customer_id
from Customer
group by customer_id
having count(distinct product_key)=(select count(*) from Product)
测试结果
1070. 产品销售分析 III
本题链接
个人解题思路
先根据product_id进行分组查询,查询product_id和其对应的最小年份再在条件过滤语句中写在上述条件内的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);
测试结果
好文推荐
发表评论