首页 > 试题广场 >

统计salary的累计和running_total

[编程题]统计salary的累计和running_total
  • 热度指数:124929 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
按照salary的累计和running_total,其中running_total为前两个员工的salary累计和,其他以此类推。 具体结果如下Demo展示。。
注意:running_total要的是对在职员工的salary进行cumulative sum,在职员工的筛选条件为to_date = "9999-01-01"
CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
输出格式:
emp_no salary running_total
10001 88958 88958
10002 72527 161485
10003 43311 204796
10004 74057 278853
10005 94692 373545
10006 43311 416856
10007 88070 504926
10009 95409 600335
10010 94409 694744
10011 25828 720572
示例1

输入

drop table if exists  `salaries` ; 
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
INSERT INTO salaries VALUES(10001,60117,'1986-06-26','1987-06-26');
INSERT INTO salaries VALUES(10001,62102,'1987-06-26','1988-06-25');
INSERT INTO salaries VALUES(10001,66074,'1988-06-25','1989-06-25');
INSERT INTO salaries VALUES(10001,66596,'1989-06-25','1990-06-25');
INSERT INTO salaries VALUES(10001,66961,'1990-06-25','1991-06-25');
INSERT INTO salaries VALUES(10001,71046,'1991-06-25','1992-06-24');
INSERT INTO salaries VALUES(10001,74333,'1992-06-24','1993-06-24');
INSERT INTO salaries VALUES(10001,75286,'1993-06-24','1994-06-24');
INSERT INTO salaries VALUES(10001,75994,'1994-06-24','1995-06-24');
INSERT INTO salaries VALUES(10001,76884,'1995-06-24','1996-06-23');
INSERT INTO salaries VALUES(10001,80013,'1996-06-23','1997-06-23');
INSERT INTO salaries VALUES(10001,81025,'1997-06-23','1998-06-23');
INSERT INTO salaries VALUES(10001,81097,'1998-06-23','1999-06-23');
INSERT INTO salaries VALUES(10001,84917,'1999-06-23','2000-06-22');
INSERT INTO salaries VALUES(10001,85112,'2000-06-22','2001-06-22');
INSERT INTO salaries VALUES(10001,85097,'2001-06-22','2002-06-22');
INSERT INTO salaries VALUES(10001,88958,'2002-06-22','9999-01-01');
INSERT INTO salaries VALUES(10002,72527,'1996-08-03','1997-08-03');
INSERT INTO salaries VALUES(10002,72527,'1997-08-03','1998-08-03');
INSERT INTO salaries VALUES(10002,72527,'1998-08-03','1999-08-03');
INSERT INTO salaries VALUES(10002,72527,'1999-08-03','2000-08-02');
INSERT INTO salaries VALUES(10002,72527,'2000-08-02','2001-08-02');
INSERT INTO salaries VALUES(10002,72527,'2001-08-02','9999-01-01');
INSERT INTO salaries VALUES(10003,40006,'1995-12-03','1996-12-02');
INSERT INTO salaries VALUES(10003,43616,'1996-12-02','1997-12-02');
INSERT INTO salaries VALUES(10003,43466,'1997-12-02','1998-12-02');
INSERT INTO salaries VALUES(10003,43636,'1998-12-02','1999-12-02');
INSERT INTO salaries VALUES(10003,43478,'1999-12-02','2000-12-01');
INSERT INTO salaries VALUES(10003,43699,'2000-12-01','2001-12-01');
INSERT INTO salaries VALUES(10003,43311,'2001-12-01','9999-01-01');

输出

emp_no|salary|running_total
10001|88958|88958
10002|72527|161485
10003|43311|204796
select emp_no  
,salary
,sum(salary)over(order by emp_no  rows  2 preceding)running_total
from salaries
where to_date='9999-01-01'
发表于 2024-11-10 16:29:46 回复(0)
这种一看题意就知道有累加,而且输出肯定是需要多行多列数据,所以首选窗口函数来解决
窗口函数中
partition by是用来分区的
order by 是用来排序的
rows或range 是用来定义窗口大小和范围的
本题需要得到前两个员工的salary累计和
所以选择rows,而rows基于物理行的位置来定义窗口,通常与between...and...连用
知识拓展: 当前行--current row
                  第一行--unbounded preceding
                  最后一行--unbounded following
                  当前行的前n行-- n preceding
                  当前行的后n行-- n following

根据题意:窗口要从第一行开始 到当前行结束
所以选择 rows between unbounded preceding and current row



SELECT
    emp_no,
    salary,
    sum( salary ) over ( rows BETWEEN unbounded preceding AND current ROW ) AS running_tota 
FROM
    salaries 
WHERE
    to_date = "9999-01-01"
发表于 2024-09-12 11:22:13 回复(0)
select emp_no,salary,sum(salary) over(rows between unbounded preceding and current row) from salaries where to_date='9999-01-01'

窗口函数yyds
发表于 2024-08-16 14:40:02 回复(0)
有没有大佬可以解释一下为什么需要“where to_date = "9999-01-01”这一句呀???题目里面也没有限制时间呀
发表于 2024-08-13 15:53:52 回复(0)
select
    emp_no,
    salary,
    sum(salary) over (order by emp_no) running_total
from salaries
where to_date='9999-01-01'
发表于 2024-06-10 17:50:46 回复(0)
select 
    emp_no,
    salary, 
    sum(salary) over( order by emp_no asc) as running_total
from salaries where to_date ='9999-01-01'
order by 1 
;

发表于 2024-06-04 19:42:09 回复(0)
select
emp_no,
salary,
sum(salary) over(order by emp_no) as running_total
from  salaries where to_date='9999-01-01'
发表于 2024-05-29 10:25:59 回复(0)
select emp_no,salary,sum(t.salary) over(order by emp_no asc)as running_total 
from (select emp_no,salary
    from salaries
    where to_date = '9999-01-01'
) t

发表于 2024-04-22 17:05:09 回复(0)
SELECT
    emp_no,
    salary,
    sum(salary) OVER(ORDER BY emp_no) AS running_total
FROM salaries 
WHERE to_date = '9999-01-01'
GROUP BY emp_no, salary;

发表于 2024-04-03 20:45:03 回复(0)
select emp_no,salary,sum(salary) over(order by emp_no)
from salaries
where to_date = "9999-01-01";
发表于 2024-03-07 10:06:06 回复(0)
有大佬帮忙看下这个错在哪里吗
select emp_no,salary
case when emp_no ='10001' then salary*1
else salary + lead(salary,1)over(order by emp_no)
end as running_total
from salaries
where to_date='9999-01-01'
order by emp_no asc
发表于 2024-02-22 16:14:05 回复(0)
在不支持窗口函数时的解法:
select s1.emp_no,s1.salary,sum(s2.salary) as running_total from salaries s1,salaries s2
where s1.to_date = '9999-01-01' and s2.to_date = '9999-01-01' and s1.emp_no >= s2.emp_no
group by s1.emp_no,s1.salary
发表于 2024-01-19 21:31:58 回复(0)
妈呀这题目描述的是不是有点不清楚,还以为是求在职员工一直以来的薪水合,实际上是求按照id排序的薪水和,就是说第一个员工就是自己的薪水,那第二个员工是第一个员工薪水加上自己的……
实际输出
10001
88958
88958
10002
72527
161485(注 72527+88958)
10003
43311
204796(注 43311+72527+88958)
学到的新知识点是,原来联结后面的条件还可以是不等式
SELECT s1.emp_no,s1.salary,SUM(s2.salary) AS running_total
FROM salaries AS s1
INNER JOIN salaries AS s2
ON s1.emp_no>=s2.emp_no
WHERE s1.to_date='9999-01-01'
AND s2.to_date='9999-01-01'
GROUP BY s1.emp_no,s1.salary;

发表于 2023-10-12 19:30:42 回复(0)
我的是mysql5.7,用不了开窗函数,所以用下面这个办法:

set @running_total=0;

select emp_no,salary,@running_total:=@running_total+salary running_total

from salaries s

where to_date ='9999-01-01'

order by emp_no

发表于 2023-08-25 16:18:07 回复(0)
select
    t1.emp_no,
    t1.salary,
    sum(salary) over (
        order by
            emp_no asc rows unbounded preceding
    ) running_total
from
    salaries t1
where
    t1.to_date = '9999-01-01';

发表于 2023-05-21 11:11:42 回复(0)
#4

select emp_no, salary, sum(salary)over(order by emp_no asc) as running_total
from salaries
where to_date = "9999-01-01"

发表于 2023-02-28 01:19:13 回复(0)
select emp_no,salary,
sum(salary) over(order by rn) as running_total
from (
   select emp_no,salary,
   row_number() over(order by emp_no) as rn
   from salaries
   where to_date = '9999-01-01'
)t;

发表于 2022-12-28 14:30:39 回复(0)
select emp_no,salary,
sum(salary) over(order by emp_no) as running_total
from salaries
where to_date = '9999-01-01';
我也会窗口函数了

发表于 2022-11-06 20:44:00 回复(0)
with tem as (select *, row_number()over(order by emp_no) as rn from salaries
            where to_date = '9999-01-01')

select 
    t1.emp_no,
    t1.salary,
    sum(t2.salary)
from tem t1 
join tem t2
on t1.emp_no >= t2.emp_no
group by t1.emp_no, t1.salary
order by t1.emp_no

发表于 2022-07-30 12:18:07 回复(0)
select emp_no, salary, sum(salary) over (order by emp_no) as running_total from salaries
where to_date = '9999-01-01';

发表于 2022-06-26 09:09:20 回复(0)