【问题标题】:Subtracting previous row using mysql update使用mysql更新减去上一行
【发布时间】:2022-01-24 18:49:33
【问题描述】:

数据库中的表

date amount name id
12-01 10.00 john doe 1002
12-02 10.00 john doe 1003
11-01 50.00 john doe 8976
11-02 50.00 john doe 8977
09-01 50.00 john doe 6788
09-02 50.00 john doe 6799
09-02 50.00 alicia doe 6800

结果应该是这样的:

Month amount total increase/decrease name
September 100.00 100.00 john doe
November 100.00 0 john doe
December 20.00 -80.00 john doe

【问题讨论】:

  • 12-01 不是date
  • total increase/descrease 取自之前的值是吗?
  • 是的,先生,这是对的,但是当我使用 LAG(sum(amount)) 时出现错误

标签: mysql subtraction cumulative-sum


【解决方案1】:

你可以用这样的查询来做到这一点

SELECT a1.pdate
 , SUM(a1.amount) AS amount
 , SUM(a1.total) AS total
 , a1.username AS username
FROM (
  SELECT a.*, COALESCE(a.amount+LAG(amount) OVER (ORDER BY pdate),0) AS total
  FROM am a 
  ORDER BY pdate
) AS a1
GROUP BY username,MONTH(pdate);

样本

MariaDB [bernd]> SELECT * from am;
+----+------------+--------+----------+
| id | pdate      | amount | username |
+----+------------+--------+----------+
|  1 | 2021-12-01 |  10.00 | john doe |
|  2 | 2021-12-02 |  10.00 | john doe |
|  3 | 2021-11-01 |  50.00 | john doe |
|  4 | 2021-11-02 |  50.00 | john doe |
+----+------------+--------+----------+
4 rows in set (0.02 sec)

MariaDB [bernd]> SELECT a1.pdate
    ->  , SUM(a1.amount) AS amount
    ->  , SUM(a1.total) AS total
    ->  , a1.username AS username
    -> FROM (
    ->   SELECT a.*, COALESCE(a.amount+LAG(amount) OVER (ORDER BY pdate),0) AS total
    ->   FROM am a 
    ->   ORDER BY pdate
    -> ) AS a1
    -> GROUP BY username,MONTH(pdate);
+------------+--------+--------+----------+
| pdate      | amount | total  | username |
+------------+--------+--------+----------+
| 2021-11-01 | 100.00 | 100.00 | john doe |
| 2021-12-01 |  20.00 |  80.00 | john doe |
+------------+--------+--------+----------+
2 rows in set (0.00 sec)

MariaDB [bernd]> 

【讨论】:

  • 我在我的实际数据库上使用精确查询,但不知道为什么我不能显示我想要的结果。结果是这样的 2021-09-01 5000000 0- 1st row 2021-11-03 164631903.07 334260806.14 -2nd row 2021-12-01 100177708.91 200348297.17- 3rd row 3rd column 是问题
  • @PapsiRhty ,您应该 update your question 提供更多信息。
  • @FanoFN,嗨,对不起,先生,好的,我已经更新了我的问题
  • @FanoFN 嗨,先生,我不知道这背后的原因是什么,但我在 LAG(sum(amount)) 中有一个错误,它不起作用。但是,当我删除这部分的总和时,查询工作正常,因此没有查询总和的原因,我无法得到我想要的结果。如果有其他方法可以在不使用 LAG 或任何差异方法的情况下获得相同的结果。希望你能帮助我谢谢你。
【解决方案2】:

看来这就是你要找的东西:

SELECT MONTHNAME(Last_trans) AS Month,
       name,
       total,
       prevTotal,
       total-IFNULL(prevTotal,0) AS Diff
FROM
(SELECT MAX(date) Last_trans,
       MONTH(date) mth,
       name,
       SUM(amount) total,
       LAG(SUM(amount)) OVER (PARTITION BY name ORDER BY MONTH(date)) prevTotal
FROM mytable
GROUP BY MONTH(date), name) V;

根据我的测试,这适用于 MySQL v8.0.27,如 demo fiddle。然而,在 MariaDB 上,这将返回 Invalid use of group function 错误消息。请注意,您可以将SUM()LAG() 操作分成两个子查询:

SELECT MONTHNAME(Last_trans) AS Month,
       name,
       total,
       prevTotal,
       total-IFNULL(prevTotal,0) AS Diff
FROM
(SELECT Last_trans,
        mth,
        name,
        total,
        LAG(total) OVER (PARTITION BY name ORDER BY mth) prevTotal
  FROM
     (SELECT MAX(date) Last_trans,
             MONTH(date) mth,
             name,
             SUM(amount) total
       FROM mytable
       GROUP BY MONTH(date), name) V 
  ) T

Fiddle for MariaDB

【讨论】:

  • ,您好,先生,我不知道这背后的原因是什么,但我在 LAG(sum(amount)) 中有一个错误,它不起作用。但是,当我删除这部分的总和时,查询工作正常,因此没有查询总和的原因,我无法得到我想要的结果。如果有其他方法可以在不使用 LAG 或任何差异方法的情况下获得相同的结果。希望你能帮助我谢谢你。
  • @PapsiRhty ,您可以运行SELECT version(); 并在此处发布您的 MySQL 服务器的确切版本吗?
猜你喜欢
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多