文章目录
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);
- 测试结果
发表评论