【问题标题】:How can i do Calculation on an Auto Populated table,我如何在自动填充表上进行计算,
【发布时间】:2020-11-22 05:32:12
【问题描述】:

这似乎是一个基本问题,但我似乎无法弄清楚

我有 2 张桌子:table_atable_b


SELECT * FROM `table_a`
+----+--------+----------+
| id | a_item | a_values |
+----+--------+----------+
|  1 |      1 |        5 |
|  2 |      1 |        5 |
+----+--------+----------+

SELECT * FROM `table_b`;
+--------+-------+
| a_item | total |
+--------+-------+
|      1 |    10 |
+--------+-------+
# NOTE: total is TEN  

正如它所显示的,我正在使用来自 table_a 的 SUM(a_values) 触发器,并将结果存储在 table_b 中。 我使用的触发器是:

CREATE TRIGGER totaling
    AFTER INSERT ON table_a
    FOR EACH ROW
    BEGIN
        INSERT INTO table_b(a_item, total)
        SELECT a_item, SUM(a_values) FROM table_a
        GROUP by a_item
        ON DUPLICATE KEY UPDATE
        total = VALUES(total);
    END

现在可以说,我更新table_b

UPDATE table_b
    SET total = total - 5
    WHERE a_item = 1

# NOTE: I'm subtracting FIVE from previous total which was TEN

table_b 总列的结果是 5,这是预期的

SELECT * FROM `table_b`
+--------+-------+
| a_item | total |
+--------+-------+
|      1 |     5 |
+--------+-------+

到目前为止,一切正常 但是,当我在table_a 上进行插入时,计算就会消失。 示例:

INSERT INTO table_a(a_item, a_values) 
    VALUES
    (1, 5);

SELECT * FROM `table_b`;
+--------+-------+
| a_item | total |
+--------+-------+
|      1 |    15 |
+--------+-------+
# NOTE: see how the total has changed from FIVE to FIFTEEN, my expected result is TEN

我可以通过直接更新table_a 来解决这个问题,然后插入触发器只会与它的现有值求和,这将给我预期的结果。

问题是,有没有一种方法可以在不操纵table_a 并且只操纵table_b 的情况下获得所需的结果,还是我需要更改插入触发器?

谢谢。

【问题讨论】:

  • 为什么要直接更新table_b?
  • 我希望 table_a 中的数据保持不变,

标签: mysql sql database mariadb database-trigger


【解决方案1】:

考虑根本不实现总和。请改用提供总和的视图:

DROP TABLE table_b;

CREATE VIEW table_b
AS
SELECT a_item,
       sum(item_values) total
       FROM table_a
       GROUP BY a_item;

那么就不需要任何触发器,总和将始终是准确的和当前的。始终保持一致性。

【讨论】:

  • 是的,我想要一个像这样的简单查询,因为我们在查询上使用了 SUM 函数,所以查询是不可更新的,无论如何这很有帮助。谢谢
  • 我想从table_b 更新总列,但因为它使用求和函数。它受到限制
  • @Mattey:这里的重点是您不需要在此处更新总和。它始终是另一个表中的当前总和。
  • 是的,但是如果有人想从table_b 中的总数更新,而不必实际操作table_a 中的数据,有没有办法??,VIEW 方法更多有趣的是,玩弄数据,而不是在 table_a 中的原始插入上进行操作
  • @Mattey:所以table_b 中的总和不一定反映table_a 中值的总和,但是它们应该有可能不同吗?那么,如果明确不想要这种完整性,那么一个观点的主要论点——确保完整性——是没有意义的。
【解决方案2】:

您想要TABLE table_b 还是VIEW table_b?你不能两者兼得。

TABLE 是磁盘上的一堆数据。 VIEW 没有“物化”(至少在 MySQL 中没有)。它只是用于读取基础表中数据的语法糖。因此,VIEW 可以反映基础表中当前的内容。

阅读 VIEW 与阅读 TABLE 的方式相同,即使用 SELECT

当您向表中添加行时,它们会立即出现在视图中。当您阅读视图时,会立即重新计算总和。

OK, "有些视图是可更新的,对它们的引用可用于在数据更改语句中指定要更新的表。即可以在UPDATE、DELETE或INSERT等语句中使用它们来更新基础表。” (引用手册)。但不要那样做。至少在您更好地处理表格和不可更新的视图之前不会。

【讨论】:

  • 感谢您的回复,我已经找到了解决方案,我会尝试根据自己的问题回答。
【解决方案3】:

我认为您想要的触发器是保持 b 中的总和,而不是重置它。那将是:

CREATE TRIGGER totaling
AFTER INSERT ON table_a
FOR EACH ROW
BEGIN
    INSERT INTO table_b (a_item, total)
        VALUES (new.a_item, new.total)
        ON DUPLICATE KEY UPDATE total = total + VALUES(total);
END;

您可能还需要UPDATE 触发器。

【讨论】:

    【解决方案4】:

    我对这个问题的解决方案是在table_b 上使用直接查询。 而不是从使用触发器的table_a 进行求和和分组,而是使用一个过程在两个表上插入

    它本身插入/更新了table_b

    INSERT INTO table_b(a_item, total)
        SELECT a_item, total + @var FROM table_b WHERE a_item = @var2
        GROUP BY a_item
        ON DUPLICATE KEY UPDATE
        total = VALUES(total);
    # NOTE: the arithmetic operator doesn't have to be an addition.
    # NOTE: @var is used as in a broad sense(not necessary as a MySQL variable).
    

    希望我已经说清楚了,并且有人认为这个答案很有帮助。 干杯:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多