表格和架构设置
考虑以下表格和触发器,
CREATE TABLE t1 (
c1 int,
c2 text,
c3 text,
m1 int,
m2 int,
primary key (c1,c2,c3)
);
CREATE TABLE t2 (
c1 int,
c2 text,
c3 text,
aggm int,
primary key (c1,c2,c3)
);
CREATE OR REPLACE FUNCTION aggregation_of_t1() RETURNS TRIGGER AS $t1$
BEGIN
INSERT INTO t2(c1, c2,c3,aggm)
VALUES (new.c1, new.c2, new.c3, new.m1 + new.m2)
ON CONFLICT (c1,c2,c3)
DO UPDATE SET aggm = t2.aggm + new.m1 + new.m2;
RETURN NULL;
END;
$t1$ LANGUAGE plpgsql;
CREATE TRIGGER aggregate_trigger AFTER INSERT OR UPDATE ON t1 FOR EACH ROW EXECUTE PROCEDURE aggregation_of_t1();
t1:主表包含c1,c2,c3标识符的m1,m2列(标记) t2:我希望这个表是m1和m2的聚合,用于t1中的所有唯一值(c1,c2,c3)。
问题
我看到t2(即aggm)中的聚合值对于我正在进行的每个插入都加倍。
输出
root=> select * from t1;
c1 | c2 | c3 | m1 | m2
----+----+----+----+----
(0 rows)
root=> select * from t2;
c1 | c2 | c3 | aggm
----+----+----+------
(0 rows)
root=> insert into t1 (c1,c2,c3,m1,m2) values (113,'URL-1','ID-1',23,22) ON CONFLICT (c1,c2,c3) DO UPDATE SET m1 = t1.m1+23, m2 = t1.m2 + 22;
INSERT 0 1
root=> select * from t1;
c1 | c2 | c3 | m1 | m2
-----+-------+------+----+----
113 | URL-1 | ID-1 | 23 | 22
(1 row)
root=> select * from t2;
c1 | c2 | c3 | aggm
-----+-------+------+------
113 | URL-1 | ID-1 | 45
(1 row)
root=> insert into t1 (c1,c2,c3,m1,m2) values (113,'URL-1','ID-1',10,11) ON CONFLICT (c1,c2,c3) DO UPDATE SET m1 = t1.m1+10, m2 = t1.m2 + 11;
INSERT 0 1
root=> select * from t2;
c1 | c2 | c3 | aggm
-----+-------+------+------
113 | URL-1 | ID-1 | 111
(1 row)
root=> select * from t1;
c1 | c2 | c3 | m1 | m2
-----+-------+------+----+----
113 | URL-1 | ID-1 | 33 | 33
(1 row)
问题:我不期待t2中的值111。相反,我期待66
在这里(即23 + 22(第一次插入)和10 + 11(第二次插入))。
我认为在第二次插入时它会将其视为45 + 45 + 21 = 111。
我在这里做的错误是什么?
答案 0 :(得分:1)
new
是写入您的表格的记录,其中m1
和m2
都是33。
所以t2.aggm + new.m1 + new.m2
是45 + 33 + 33 = 111。
要获得您想要的结果(例如aggm = 45 + 10 + 11
),您应该将AFTER UPDATE
案例移至单独的触发器,其中包含以下内容:
UPDATE t2 SET aggm = aggm + (new.m1 - old.m1) + (new.m2 - old.m2);