2017-05-17 161 views
0

使用MySQL。我想获得累积总和。MySQL中的累积和

这是我的表

CREATE TABLE `user_infos` 
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
(..) 
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
PRIMARY KEY (`id`)) 

而我想要得到的是

+-------+-------+----------------+ 
| month | count | cumulative_sum | 
+-------+-------+----------------+ 
| 01 | 100 | 100   | 
| 02 | 101 | 201   | 
| ... | 110 | 311   | 
| 12 | 200 | 511   | 
+-------+-------+----------------+ 

但结果是

+-------+-------+----------------+ 
| month | count | cumulative_sum | 
+-------+-------+----------------+ 
| 01 | 100 | 100   | 
| 02 | 101 | 101   | 
| ... | 110 | 110   | 
| 12 | 200 | 200   | 
+-------+-------+----------------+ 

这是我的错查询..

select 
    T1.Month,T1.Count, 
    @runnung_total := (@running_total + T1.Count) as cumulative_sum 
from (
    select date_format(created_at,'%m') as Month,count(1) as Count from users 
      where date_format(created_at,'%Y')='2016' 
      group by(date_format(created_at,'%m')) 
    union 
    select date_format(created_at,'%m') as Month,count(1) as Count from users 
      where date_format(created_at,'%Y')='2017' 
      group by(date_format(created_at,'%m'))) as T1 
join (select @running_total := 0) as R1; 

我提到this。我的代码有什么问题?

+0

。 。你的代码应该计算运行,但它可以被简化。 –

回答

0

可以实现在两个步骤:首先是让每个年份和月份

select concat(year(created_at), lpad(month(created_at), 2, '0')) as ye_mo, 
     count(*) as cnt 
from users 
group by concat(year(created_at), lpad(month(created_at), 2, '0')) 

然后用自己加入它的总和,其与以前的不同匹配的每一行

select t1.ye_mo, sum(t2.cnt) 
from (
      select concat(year(created_at), lpad(month(created_at), 2, '0')) as ye_mo, 
        count(*) as cnt 
      from users 
      group by concat(year(created_at), lpad(month(created_at), 2, '0')) 
     ) t1 
join (
      select concat(year(created_at), lpad(month(created_at), 2, '0')) as ye_mo, 
        count(*) as cnt 
      from users 
      group by concat(year(created_at), lpad(month(created_at), 2, '0')) 
     ) t2 
on  t1.ye_mo >= t2.ye_mo 
group by t1.ye_mo 
order by t1.ye_mo 

编辑

上面的查询假设您希望运行总和在不同年份增加。如果你想只显示个月,并聚集在同一个月的不同年份的值,可以更改ID这样

select t1.mnt, sum(t2.cnt) 
from (
      select month(created_at) as mnt, 
        count(*) as cnt 
      from userss 
      group by month(created_at) 
     ) t1 
join (
      select month(created_at) as mnt, 
        count(*) as cnt 
      from userss 
      group by month(created_at) 
     ) t2 
on  t1.mnt >= t2.mnt 
group by t1.mnt 
order by t1.mnt 

最后,如果你想运行总和在每年年初重置,你可以做这样的

select t1.yr, t1.mn, sum(t2.cnt) 
from (
      select year(created_at) as yr, month(created_at) as mn, 
        count(*) as cnt 
      from userss 
      group by year(created_at), month(created_at) 
     ) t1 
join (
      select year(created_at) as yr, month(created_at) as mn, 
        count(*) as cnt 
      from userss 
      group by year(created_at), month(created_at) 
     ) t2 
on  t1.yr = t2.yr and 
     t1.mn >= t2.mn 
group by t1.yr, t1.mn 
order by t1.yr, t1.mn 

所有三个版本可以在行动中可以看出here

+0

谢谢你的好意!我学到的比我想象的要多。 – Centell

+0

我不明白在Toad for SQL中出现'year_month'错误。 “MySQL数据库错误:您的SQL语法错误;检查与您的MySQL服务器版本相对应的手册,以便在'year_month',count(*)as用户组的cnt附近使用正确的语法by concat(year(create '在第1行' 如果我更改'year_month'就像'yearMonth'那么它会消失,我不明白为什么 – Centell

+0

这可能是因为这是一个保留的关键字,我用不同的别名更新了我的第一个选项,再试一次 –

0

变量是正确的道路要走。您可以简化查询:

select m.Month, m.cnt, 
    (@running_total := (@running_total + m.cnt)) as cumulative_sum 
from (select month(created_at) as Month, count(*) as cnt 
     from users 
     where year(created_at) in (2016, 2017) 
     group by month(created_at) 
    ) m cross join 
    (select @running_total := 0) params 
order by m.Month; 
+0

谢谢。你的代码比我的更漂亮,但结果和我的代码一样.. – Centell

+0

@Centell ......有一个错字, '@ runnung_total'而不是'running_total'。这与您的查询看起来是同样的问题。 –

+0

再次感谢您!它运作良好。 – Centell