Since you didn't show the user / todo tables, we can only suppose.
Attention to Postgres CREATE TRIGGER::
CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] }
ON table_name
[ FROM referenced_table_name ]
[ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
[ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ]
[ FOR [ EACH ] { ROW | STATEMENT } ]
[ WHEN ( condition ) ]
EXECUTE { FUNCTION | PROCEDURE } function_name ( arguments )
Lookout for :
referencing new table as NEW
Try out this example and see if it suits you. Your mileage may vary.
-- newtable definition
-- DROP table created_todos ;
-- drop table TODO;
-- drop function f_updateTodoCounts;
-- drop function f_insertTodoCounts;
CREATE TABLE todo (
u_created_by integer not null,
todowhat integer not null,
primary key( u_created_by, todowhat )
);
CREATE TABLE created_todos (
u_created_by integer ,
num_of_todos integer ,
primary key ( u_created_by )
);
create function f_insertTodoCounts() returns trigger
as $f_insertTodoCounts$
declare
u_cb INTEGER;
begin
select count(td.*)
into u_cb
from created_todos td , new N
where N.u_created_by = td.u_created_by;
if u_cb < 1 then
insert into created_todos
select I.u_created_by ,1
from NEW I;
else
update created_todos CT
set num_of_todos = cnt_todos
from ( select count(T.todowhat) cnt_todos, T.u_created_by
from todo T
group by T.u_created_by) TD
where TD.u_created_by = CT.u_created_by
;
end if;
return new;
end;
$f_insertTodoCounts$ language plpgsql;
create function f_updateTodoCounts() returns trigger
as $f_updateTodoCounts$
begin
update created_todos CT
set num_of_todos = cnt_todos
from ( select count(1) cnt_todos, u_created_by
from todo T inner join NEW I on (I.u_created_by = T.u_created_by) ) TD
where TD.u_created_by = CT.u_created_by;
return new;
end;
$f_updateTodoCounts$ language plpgsql;
create trigger insTodoCounts
after insert on todo
referencing new table as NEW
for each row
execute function f_insertTodoCounts();
create trigger updTodoCounts
after update on todo
referencing new table as NEW
for each row
execute function f_updateTodoCounts();
insert into todo values ( 1 ,1 );
insert into todo values (2,1 );
insert into todo values (1,2);
insert into todo values (1,3);
insert into todo values (1,4);
insert into todo values (1,5);
insert into todo values (1,6);
insert into todo values (2,5);
insert into todo values (3,5);
insert into todo values (4,7);
select * from created_todos;