首页 > 解决方案 > MySQL 基于列值运行总计

问题描述

我正在尝试生成一个基于列的运行总计表

假设我有一张这样的桌子:

公司 利润
谷歌 2020 16
谷歌 2021 18
苹果 2020 20
苹果 2021 26
bp 2020 15
bp 2021 10

期望的结果是

公司 利润 暨利润
谷歌 2019 16 16
谷歌 2020 18 34
谷歌 2021 13 47
苹果 2019 20 20
苹果 2020 26 46
苹果 2021 21 67
bp 2019 15 15
bp 2020 10 25
bp 2021 17 42

我找到了一种方法,但它会不断增加而不需要寻找公司名称。每个公司都应该有自己的运行总数。

这是我的方式:

SELECT company, year, profit, 
CAST((@cum_profit:= @cum_profit + profit) AS DECIMAL(16, 2)) AS cum_profit
FROM table  
GROUP BY company, year) AS t
JOIN(SELECT @cum_profit:= 0) AS tmp;

结果是连续运行总计,但我需要每个公司自己的运行总计。

标签: mysqlsqlgroup-byaggregate

解决方案


对于旧版本的 MySQL,您可以使用子查询来完成,在 MySQL 8.0 及更高版本中,您可以使用sum()over()按公司列分区的窗口函数。

模式和插入语句:

 create table company_profit(company varchar(50), year int, profit int );
 insert into company_profit values('google',    2019,   16);    
 insert into company_profit values('google',    2020,   18);    
 insert into company_profit values('google',    2021,   13);    
 insert into company_profit values('apple', 2019,   20);    
 insert into company_profit values('apple', 2020,   26);    
 insert into company_profit values('apple', 2021,   21);    
 insert into company_profit values('bp',    2019,   15);    
 insert into company_profit values('bp',    2020,   10);    
 insert into company_profit values('bp',    2021,   17);    

使用子查询运行总查询(对于 MySQL 8.0 之前的旧版本)

 select company,year,profit,
 (select sum(profit) from company_profit c where c.company=cp.company and c.year<=cp.year) as cum_profit
 from company_profit cp

输出:

公司 利润 cum_profit
谷歌 2019 16 16
谷歌 2020 18 34
谷歌 2021 13 47
苹果 2019 20 20
苹果 2020 26 46
苹果 2021 21 67
bp 2019 15 15
bp 2020 10 25
bp 2021 17 42

使用窗口函数运行总查询(对于 MySQL 8.0 及更高版本):

 select company,year,profit,sum(profit)over( partition by company order by company,year) as cum_profit
 from company_profit

输出:

公司 利润 cum_profit
苹果 2019 20 20
苹果 2020 26 46
苹果 2021 21 67
bp 2019 15 15
bp 2020 10 25
bp 2021 17 42
谷歌 2019 16 16
谷歌 2020 18 34
谷歌 2021 13 47

db<小提琴在这里


推荐阅读