【问题标题】:MySQL Trigger SumMySQL 触发器总和
【发布时间】:2021-09-14 19:32:59
【问题描述】:

我想要一个更新前触发器的帮助,它有条件地对日期和 ID 匹配的金额列进行求和,并且只显示变量为“总计”的总和。

id | day | variable | amount
-: | :------ | :------- | :-----
1 | Monday | Total | null
1 | Monday | null | 1
1 | Monday | null | 2
1 | Monday | null | 3
1 | Tuesday | Total | null
1 | Tuesday | null | 1
1 | Tuesday | null | 2
1 | Tuesday | null | 3
2 | Monday | Total | null
2 | Monday | null | 1
2 | Monday | null | 2
2 | Monday | null | 3
2 | Tuesday | Total | null
2 | Tuesday | null | 1
2 | Tuesday | null | 2
2 | Tuesday | null | 3

有没有办法控制 sum 函数,使其不会更新每个总计,除非关联的值已更新?即,我不希望在周二行内的值发生变化或其他 ID 发生变化时重新计算周一总计。

小提琴:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=fc3939aa508002dab7f2af45611717cf

【问题讨论】:

    标签: mysql


    【解决方案1】:

    请注意,MySQL 根据documentation,在触发器中更新同一张表中的其他行有限制。

    存储的函数或触发器不能修改已被调用函数或触发器的语句使用(用于读取或写入)的表。

    如果下面的 SQL 语句可以工作

    UPDATE tb1 t1
    JOIN (
      SELECT id, day, SUM(amount) as total
      FROM tb1 t
      WHERE id = 1 AND day = 'Monday' AND variable is NULL
      GROUP BY id, day
    ) t2 ON t1.id = t2.id AND t1.day = t2.day AND t1.variable = 'Total'
    SET t1.amount = t2.total;
    

    那么它在触发器内部的实现会抛出错误

    您不能在 FROM 子句中指定目标表 'tb1' 进行更新

    但你可以在没有触发器的情况下创建视图

    SELECT 
      id, day, variable,
      CASE WHEN variable = 'Total' 
           THEN (
             SELECT SUM(amount) FROM tb1 t1 
             WHERE t1.id = t.id AND t1.day = t.day AND t1.variable IS NULL
           ) 
           ELSE amount
      END AS amount
    FROM tb1 t  
    

    或者,甚至可以使用Total 完全删除所有行并使用WITH ROLLUP 子句检索它们。

    SELECT 
      id, 
      day,
      CASE WHEN amount IS NULL THEN 'Total' END AS variable,
      SUM(amount) AS amount
    FROM tb1
    GROUP BY id, day, amount
    WITH ROLLUP
    HAVING id IS NOT NULL AND day IS NOT NULL
    

    db<>fiddle

    【讨论】:

      猜你喜欢
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多