每个月中每个唯一ID的累计总和

时间:2018-01-19 09:20:02

标签: mysql sql sum cumulative-sum

我正在尝试计算所有客户的累积利润,我从here找到了一个很好的参考。但是,我的表由超过1个客户组成,应该有自己的累计利润。以下是表'客户'我已经拥有了。

| Year | Month | id  | profit | cumulative |
| 2017 |   1   | 123 |  1000  |            |
| 2017 |   2   | 123 |  -200  |            |
| 2017 |   3   | 123 |  500   |            |
| 2017 |   1   | 456 |  500   |            |
| 2017 |   2   | 456 |  100   |            |
| 2017 |   3   | 456 |  200   |            |

如果我使用的是这样的SQL代码:

SET @csum := 0;
UPDATE client
SET cumulative = (@csum := @csum + profit);

我得到的结果是这样的:

| Year | Month | id  | profit | cumulative |
| 2017 |   1   | 123 |  1000  |    1000    |
| 2017 |   2   | 123 |  -200  |    800     |
| 2017 |   3   | 123 |  500   |    1300    |
| 2017 |   1   | 456 |  500   |    1800    |
| 2017 |   2   | 456 |  100   |    1900    |
| 2017 |   3   | 456 |  200   |    2100    |

我期望获得的是这样的:

| Year | Month | id  | profit | cumulative |
| 2017 |   1   | 123 |  1000  |    1000    |
| 2017 |   2   | 123 |  -200  |    800     |
| 2017 |   3   | 123 |  500   |    1300    |
| 2017 |   1   | 456 |  500   |    500     |
| 2017 |   2   | 456 |  100   |    600     |
| 2017 |   3   | 456 |  200   |    800     |

我也尝试按年份,月份和ID进行分组,但它不起作用。基本上,我想要每个月的每个独特客户的累计金额。你知道如何解决这个问题吗?提前谢谢。

3 个答案:

答案 0 :(得分:1)

我会避免使用局部变量,因为结果有时可能与预期不同,并且DBMS可以更好地优化基于集合的方法。请改用子查询或自联接:

"hello world"

因此在SELECT c1.*, (SELECT SUM(c2.profit) FROM client c2 WHERE (c2.year < c1.year or (c2.year = c1.year and c2.month <= c1.month)) and c2.id = c1.id ) AS cumulative_sum FROM TABLE client c1 它可以喜欢这个

update

sqlfiddle demo(感谢@JohnWoo获取数据)

答案 1 :(得分:1)

局部变量仅在查询中与ORDER BY一起正常工作。

SET @csum := 0, @id:=NULL;
UPDATE client
   SET cumulative = (@csum := if(id=@id,@csum,0) + profit), id=(@id:=id)
ORDER BY id, year, month;

sqlfiddle.com

上的示例

或者更快:... SET cumulative = (@csum := if(id=@id, @csum, 0*(@id:=id) ) + profit)。这个comare存储了ID和当前ID,如果ID相同则返回存储的SUM,如果ID不同,则返回0(并存储新ID)。

答案 2 :(得分:1)

您可以使用变量执行此操作,但您需要非常小心。使用变量时,您希望所有操作都在一个语句中 - 因为MySQL不保证语句评估的顺序:

D / MainActivity: loadPrefsFromDB: onDataChange