使用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 :(得分:1)
您可以分两步完成:首先获得每年和每月的总和
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
答案 1 :(得分:1)
变量是正确的方法。您可以简化查询:
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;
答案 2 :(得分:0)
从MySQL 8开始,理想的计算累计总和的方法是使用SQL标准window functions,而不是特定于供应商的方法,而不是严格声明性的使用局部变量的方法。您的查询可以编写如下:
WITH data(month, count) AS (
SELECT date_format(create_at, '%m') AS month, count(*) AS count
FROM users
GROUP BY date_format(create_at, '%m')
)
SELECT
month,
count,
sum(count) OVER (ORDER BY month) AS cumulative_sum
FROM data