sql - 自动维护父表中 child 的总数

标签 sql postgresql triggers plpgsql

我有父子表,我想在其中自动存储父记录中子项的计数。更新不是很频繁,但读取很频繁,所以这个数字(对我来说)似乎很适合缓存。表格可能看起来像这样:

create table parent(
   id SERIAL PRIMARY KEY,
   numchildren integer not null default 0
);

create table child(
  id serial primary key
  parent_id integer NOT NULL REFERENCES parent(id)
);

我添加了一个触发器来更新 numchildren 但它总是将 numchildren 设置为 child 表中的全部记录,不仅仅是特定 parent 的计数。

CREATE OR REPLACE FUNCTION run_after_change() RETURNS TRIGGER AS $$
BEGIN
  IF TG_OP = 'DELETE' THEN
    UPDATE parent 
       SET numchildren = (SELECT COUNT(*) FROM child WHERE OLD.parent_id = parent.id) 
    WHERE OLD.parent_id = parent.id;
    RETURN OLD;
  ELSIF TG_OP = 'UPDATE' OR TG_OP = 'INSERT' THEN
    UPDATE parent 
      SET numchildren = (SELECT COUNT(*) FROM child WHERE NEW.parent_id = parent.id) 
    WHERE NEW.parent_id = parent.id;
    RETURN NEW;
  END IF;
END; $$ language 'plpgsql';

CREATE TRIGGER after_change 
  AFTER DELETE OR INSERT OR UPDATE ON child 
  FOR EACH ROW EXECUTE PROCEDURE run_after_change();

我做错了什么?

最佳答案

count(*) 查询的 where 子句是错误的。

parent.id 应该是 parent_id 应该是:

SELECT COUNT(*) FROM child WHERE parent_id = NEW.parent_id

(或 OLD.parent_id 用于 DELETE 部分)

关于sql - 自动维护父表中 child 的总数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41728515/

相关文章:

mysql - 更新行中具有不同值的列

用于插入和更新的 MySQL Fire 触发器

sql - 聚合函数和 OrderBy

sql - 小计行的索引?

python - 手动安排Azure中Postgresql的备份?

sql - Postgres :Get the latest record from a table

SQL Server : update new record on insert

mysql - 从触发器调用的存储过程中的动态语句的解决方法

mysql - 导入庞大的mysql数据库访问

mysql - 如何让这个查询变得高效?