题目描述
(通过次数12,487 | 提交次数28,952,通过率43.13%)
Employee 表保存了一年内的薪水信息。 请你编写 SQL 语句,对于每个员工,查询他除最近一个月(即最大月)之外,剩下每个月的近三个月的累计薪水(不足三个月也要计算)。 结果请按 Id 升序,然后按 Month 降序显示。 示例: 输入: | Id | Month | Salary | |----|-------|--------| | 1 | 1 | 20 | | 2 | 1 | 20 | | 1 | 2 | 30 | | 2 | 2 | 30 | | 3 | 2 | 40 | | 1 | 3 | 40 | | 3 | 3 | 60 | | 1 | 4 | 60 | | 3 | 4 | 70 | 输出: | Id | Month | Salary | |----|-------|--------| | 1 | 3 | 90 | | 1 | 2 | 50 | | 1 | 1 | 20 | | 2 | 1 | 20 | | 3 | 3 | 100 | | 3 | 2 | 40 | 解释: 员工 '1'除去最近一个月(月份 '4'),有三个月的薪水记录:月份 '3'薪水为40,月份 '2'薪水为 30,月份 '1'薪水为 20。 所以近 3 个月的薪水累计分别为(40 + 30 + 20) =90,(30 + 20) = 50 和 20。 | Id | Month | Salary | |----|-------|--------| | 1 | 3 | 90 | | 1 | 2 | 50 | | 1 | 1 | 20 | 员工 '2' 除去最近的一个月(月份 '2')的话,只有月份 '1' 这一个月的薪水记录。 | Id | Month | Salary | |----|-------|--------| | 2 | 1 | 20 | 员工 '3' 除去最近一个月(月份 '4')后有两个月,分别为:月份 '3' 薪水为 60 和 月份 '2' 薪水为 40。所以各月的累计情况如下: | Id | Month | Salary | |----|-------|--------| | 3 | 3 | 100 | | 3 | 2 | 40 | 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/find-cumulative-salary-of-an-employee
//测试数据 Create table If Not Exists Employee (id int, month int, salary int); insert into Employee (id, month, salary) values ('1', '1', '20'); insert into Employee (id, month, salary) values ('2', '1', '20'); insert into Employee (id, month, salary) values ('1', '2', '30'); insert into Employee (id, month, salary) values ('2', '2', '30'); insert into Employee (id, month, salary) values ('3', '2', '40'); insert into Employee (id, month, salary) values ('1', '3', '40'); insert into Employee (id, month, salary) values ('3', '3', '60'); insert into Employee (id, month, salary) values ('1', '4', '60'); insert into Employee (id, month, salary) values ('3', '4', '70'); insert into Employee (id, month, salary) values ('1', '7', '90'); insert into Employee (id, month, salary) values ('1', '8', '90');
解题思路
这是一道困难题,通过率只有43.13%。确实有些难度。但我觉得,难度并不体现在SQL有多难写,而是体现在细心程度上。就像我第一次提交失败,就是因为忘记做ORDER BY了。
题目要求,不计算每个id的最大月份的统计数据。那么可以先把这部分数据先过滤掉。再统计每个月份最近3个月的累计数据,最后排序返回即可。
取出最大月份并过滤,以及排序都比较容易实现。
难点主要在于如何统计每个月份最近3个月的累计数据。
对于累计数据的计算,一般来说,都可以通过自关联,然后限定合适的关联条件,再分组汇总来实现。
具体到统计最近3个月的数据。那么,可以把当月、上月、上上月的数据发散到当月来,再以当月来汇总统计实现。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
with tmp as ( select a.* from Employee a where (a.id,a.month) not in (select id,max(month) from Employee group by id) ) select a.id,a.month,sum(b.salary) Salary from tmp a inner join tmp b on a.id = b.id and b.month between a.month - 2 and a.month group by a.id,a.month order by a.id,a.month desc;
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。