如何在自动填充的表上进行计算,

idv4meu8  于 2021-07-26  发布在  Java
关注(0)|答案(4)|浏览(243)

这似乎是一个基本问题,但我似乎弄不明白
我有两张table: table_a 以及 table_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` ,并将结果存储在 `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` ,则insert触发器将只与它的现有值求和,这将给出我的预期结果。
问题是,有没有一种方法可以让我不需要操纵就能得到想要的结果 `table_a` ,并且仅操纵 `table_b` ,还是需要更改插入触发器?
谢谢。
vjhs03f7

vjhs03f71#

考虑一下不要把总数具体化。请改用一个视图,该视图提供以下总和:

DROP TABLE table_b;

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

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

bxjv4tth

bxjv4tth2#

你想喝点什么吗 TABLE table_b 或者 VIEW table_b ? 你不能两者兼得。
TABLE 是磁盘上的一堆数据。一 VIEW 不是“物化的”(至少在mysql中不是)。它只是读取底层表中数据的语法糖。因此 VIEW 只能反映基础表中当前的内容。
你读了一本书 VIEW 就像你读一本书一样 TABLE ,即使用 SELECT .
当您向表中添加行时,它们会立即出现在视图中。读取视图时,将立即重新计算总和。
好的,“有些视图是可更新的,对它们的引用可以用来指定要在数据更改语句中更新的表。也就是说,您可以在诸如update、delete或insert之类的语句中使用它们来更新基础表的内容。”(引用手册)。但别那么做。至少在更好地处理表和不可更新的视图之前是这样。

fhg3lkii

fhg3lkii3#

我认为你想要的触发因素是把总数保持在 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 同时触发。

agxfikkp

agxfikkp4#

我解决这个问题的方法是直接查询 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).

希望我已经说清楚了,有人觉得这个答案很有用。干杯:)

相关问题