我有两张桌子。第一个表包含按年份和territory_id的一些数据更改。
territory_id year count_sth
430000000 2015 130
431000000 2015 15
433200000 2015 75
433600000 2015 40
431000000 2014 13
433200000 2014 20
...
第二个表包含parent-id形式的parent-id之间的关系。
territory_id parent_id desc_ru
430000000 0 'abc'
431000000 430000000 'sdf'
433200000 430000000 'jkl'
433210000 433200000 'bnm'
...
我想将列count_sth
(table1)的值设置为按年份划分的子组的值的总和。它应该自动更新。每当我们更新count_sth
时,其中count_sth
为某个地区的父级的territory_id
的值将等于其子项的值count_sth
的总和。
怎么做?
我尝试使用函数返回触发器来更新这个(table1)表。
CREATE OR REPLACE FUNCTION table__byyear()
RETURNS trigger AS
$func$
BEGIN
UPDATE table__byyear f
SET count_sth= A.a1
from (select b.year, b.sum(count_sth) as a1, t.parent_id
from table__byyear b join admterr t
on b.territory_id = t.territory_id
GROUP by b.year, t.parent_id) A
where f.territory_id = A.parent_id and f.year = A.year
AND count_sth IS DISTINCT FROM A.a1;
RETURN NULL;
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER table__byyear_terr
BEFORE INSERT OR UPDATE ON table__byyear
FOR EACH ROW EXECUTE PROCEDURE table__byyear();
但是在这里,这个UPDATE触发器在同一个表上运行另一个UPDATE,它将再次触发触发器,因此我们得到无限递归。 指出我正确的方向。
答案 0 :(得分:0)
您可以使用以下语句一次更新行和所有父行:
with recursive hier as (
-- a row
select t.territory_id,
t.parent_id,
b.year
from table__byyear b,
admterr t
where t.territory_id = 433210000 --<< change me
and b.year = 2015 --<< change me
and t.territory_id = b.territory_id
union all
-- parent rows
select t.territory_id,
t.parent_id,
prev.year
from hier prev,
admterr t
where t.territory_id = prev.parent_id
)
update table__byyear
set count_sth = count_sth + 100 --<< change me
where (territory_id, year) in (select territory_id, year from hier);
鉴于此声明,您可能想要创建一个函数......
create function update_hier(
territory_id integer,
year integer,
delta numeric
)
returns void
as $$
with ...
update table__byyear
set count_sth = count_sth + $3
where (territory_id, year) in (select territory_id, year from hier);
$$ language sql;
...甚至创建一个带有反向更新触发器的视图来调用此函数。