【问题标题】:How to calculate reverse running sum in MySQL如何在 MySQL 中计算反向运行总和
【发布时间】:2020-09-16 12:46:32
【问题描述】:

我有这个查询,我计算了累积总和。现在,我需要计算同一个变量的反向累积和

SELECT t1.date, t1.ant, t1.hab,  
(@csum:= @csum + t1.hab) as cumulative_hab
from(
SELECT date,
        ant, 
        sum(num_habit) as hab
        from xxxxxxxxxx
        WHERE date BETWEEN CURDATE() - INTERVAL 5 DAY AND CURDATE()
        group by ant) AS t1
,(select @csum := 0) vars
order by t1.ant

我的桌子是这样的

date       ant   hab    cumulative_hab
24-05-2020  0   382,000   382,000
24-05-2020  1   28,000    410,000
24-05-2020  2   26,000    436,000
24-05-2020  3   11,000    447,000
24-05-2020  4   29,000    476,000
24-05-2020  6   6,000     482,000
24-05-2020  7   12,000    494,000
28-05-2020  8   50,000    544,000
24-05-2020  12  5,000     549,000
24-05-2020  13  6,000     555,000

我想要另一列有反向运行总和(反向累积总和),第一个值计算为 555 - 382

 date      ant   hab    cumulative_hab   reverse_cum_hab
24-05-2020  0   382,000   382,000             555,000
24-05-2020  1   28,000    410,000             173,000, 
24-05-2020  2   26,000    436,000             145,000
24-05-2020  3   11,000    447,000             119,000
24-05-2020  4   29,000    476,000             108,000
24-05-2020  6   6,000     482,000              79,000
24-05-2020  7   12,000    494,000              73,000
28-05-2020  8   50,000    544,000              61,000
24-05-2020  12  5,000     549,000              11,000
24-05-2020  13  6,000     555,000               6,000

【问题讨论】:

  • 你运行的是哪个版本的 MySQL?
  • 我使用的是 MYSQL 5.6.4
  • 这与您之前接受答案的问题有何不同?
  • 有点不同,因为我的代码发生了变化(更多日期和 sum(x)),我尝试使用您的回复,但我无法使用此代码。

标签: mysql sql group-by sum window-functions


【解决方案1】:

作为初学者:如果您运行的是 MySQL 8.0,则可以使用窗口函数轻松完成此操作:

select 
    date,
    ant,
    sum(num_habit) as hab,
    sum(sum(num_habit)) over(order by date) cumulative_hab,
    sum(sum(num_habit)) over(order by date desc) reverse_cumulative_hab
from mytable
where date between current_date - interval 5 day and current_date
group by date, ant
order by date

在早期版本中,它更复杂。我建议加入两个查询:

select t.*, r.reverse_cumulative_hab
from (
    select t.*, @csum := @csum + hab cumulative_hab
    from (
        select date, ant, sum(num_habit) as hab
        from mytable
        where date between current_date - interval 5 day and current_date
        group by date, ant
        order by date
    ) t
    cross join (select @csum := 0) x
) t
inner join (
    select t.*, @rcsum := @rcsum + hab reverse_cumulative_hab
    from (
        select date, ant, sum(num_habit) as hab
        from mytable
        where date between current_date - interval 5 day and current_date
        group by date, ant
        order by date desc
    ) t
    cross join (select @rcsum := 0) x
) r on r.date = t.date
order by t.date

这假定每个 date 没有重复的 ant

也可以简化逻辑并通过取累积和与总和之间的差来计算反向和:

select t.*, z.total_hab - t.cumulative_hab reverse_cumulative_hab
from (
    select t.*, @csum := @csum + hab cumulative_hab
    from (
        select date, ant, sum(num_habit) as hab
        from mytable
        where date between current_date - interval 5 day and current_date
        group by date, ant
        order by date
    ) t
    cross join (select @csum := 0) x
) t
cross join (
    select sum(num_habit) as total_hab
    from mytable
    where date between current_date - interval 5 day and current_date
) z
order by date

请注意,在行的排序方面,这些查询比您的原始代码更安全:记录在子查询中排序计算累积总和之前。

【讨论】:

  • 正在考虑相同的策略 +1。
  • @TheImpaler:谢谢。我尝试了另一个使用总数差异的方法(这可能更有效)。太糟糕了,OP 没有提供样本数据,所以我无法测试。
  • 我想 OP 被抑制了!
  • @JulioMoyanoBasso 。 . .第二种方案是最好的方案。你应该接受答案。
  • 嗨,谢谢。我尝试使用第三个代码,因为我有重复。我不得不做一些改变(按蚂蚁,日期和按蚂蚁,日期排序)它正在工作,但第一个值(reverse_cumulative_hab)不是总数是第二个值,最后一个值为零
猜你喜欢
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
相关资源
最近更新 更多