SQL练习00002

问题:
查询员工的累计薪水,Employee 表保存了一年内的薪水信息。请你编写 SQL 语句,对于每个员工,查询他除最近一个月(即最大月)之外,剩下每个月的近三个月的累计薪水(不足三个月也要计算)。结果请按 Id 升序,然后按 Month 降序显示。

Employee表:

IdMonthSalary
1120
2120
1230
2230
3240
1340
3360
1460
3470

输出:

IdMonthSalary
1390
1250
1120
2120
33100
3240
--建表语句:
Create table If Not Exists Employee (Id int, Month int, Salary int)
Truncate table Employee
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')

--答案1
--可以多字段not in过滤每个id中最大月份数据,通过自连接分组聚合最后排序
select
  b.Id as id,
  b.Month as month,
  sum(a.Salary) as Salary
from
  (select 
    *
  from Employee e where
    (e.Id,e.Month,e.Salary) not in
    (select
      Id,
      max(Month) as Month,
      max(Salary) as Salary
    from
      Employee group by id)) a join 
    (select 
      *
    from Employee e where
      (e.Id,e.Month,e.Salary) not in
      (select
        Id,
        max(Month) as Month,
        max(Salary) as Salary
      from
        Employee group by id)) b
      on a.Id = b.Id and a.Month<=b.Month 
      group by b.Id,b.Month order by b.Id,b.Month desc

#答案2 窗口函数
SELECT 
  Id, 
  Month, 
  Salary
FROM 
  (SELECT 
    Id, 
    Month, 
    SUM(Salary) OVER (PARTITION BY Id ORDER BY Month ROWS 2 PRECEDING) AS Salary, 
    rank() OVER (PARTITION BY Id ORDER BY Month DESC) AS r
   FROM Employee) t 
   WHERE r > 1 ORDER BY Id, Month DESC

版权声明:本文为qq_41885821原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。