【问题标题】:Postgres trigger function to update aggregated result in another tablePostgres 触发函数以更新另一个表中的聚合结果
【发布时间】:2017-12-24 04:47:07
【问题描述】:

我有两张桌子。表 x 和表 y。表 x 每天都会更新。我希望在表 x 中插入新数据后立即更新表 y。表 y 包含表 x 中每天所有更新的汇总值。 日期是日期类型,两列的其余部分是真实类型。 table_x 可以每天更新,table_y 应该会自动更新。

x

Date    Sales    product
12/12/2017   4000   2
12/12/2017   3000   1
12/12/2017   2000   1
12/12/2017   5000   3
11/12/2017   1000   3
11/12/2017   2000   4

y(待更新如下图):

Date   Sales   product
12/12/2017   14000   7
11/12/2017   3000    7

我编写了如下所示的触发器函数,但它更新每个项目而不是聚合值。

CREATE OR REPLACE FUNCTION public.rec_insert_table_y()
RETURNS trigger AS
$BODY$  
BEGIN  
INSERT INTO table_y ("Date","Sales","product")
SELECT NEW."Date",(sum(NEW."Sales")),(sum(NEW."product"))
GROUP BY NEW."Date";
RETURN NEW;

触发功能:

CREATE TRIGGER insert_into_table_y
AFTER INSERT
ON public.table_x
FOR EACH ROW
EXECUTE PROCEDURE public.rec_insert_table_y();

【问题讨论】:

  • 我在任何地方都看不到您的触发器定义、表定义和 Postgres 版本。而且您的功能也不完整。还缺少:基本信息:可以在表x 中插入新产品吗?或者只是现有产品的新行?请edit完成信息。
  • @Erwin:按照您的建议更新定义。我的 Postgres 版本是“PostgreSQL 9.5.3”。是的,每天都会在 Table_x 中插入新产品。
  • 我的这部分评论没有得到答复:Can new products be inserted in table x? or just new rows for existing products?

标签: postgresql


【解决方案1】:

您可以编写一个触发器,如果​​存在则更新聚合值,如果不存在则插入。

您还必须注意“x”表中的更新和删除:

create function y_x_trg() returns trigger
  language plpgsql
as
$body$
declare
  row_exists boolean;
begin
  if tg_op<>'INSERT' then
    update y 
      set sales = y.sales - old.sales,
          product = y.product - old.product
      where y.date = old.date
      returning true into row_exists;
  end if;
  if tg_op<>'DELETE' then
    update y 
      set sales = y.sales + new.sales,
          product = y.product + new.product
      where y.date = new.date
      returning true into row_exists;
    if row_exists is not true then
      insert into y values (new.date, new.sales, new.product);
    end if;
    return new;
  else
    return null;
  end if;
end;
$body$;

create trigger y_x_trg AFTER INSERT OR UPDATE OR DELETE ON x
    FOR EACH ROW EXECUTE PROCEDURE y_x_trg();

你可以在http://rextester.com/FVR79644看到一个运行示例

【讨论】:

  • Emilio 感谢更新,但它是否将每天的销售额和产品汇总到目标表中......? .我认为我们将不得不在日期列上使用 GROUP BY 方法。如果我错了,请纠正我。
  • 你在写。我误会了。我认为产品是一个 ID。你的例子很清楚,这是我的错。我编辑了答案以反映“y”表只有日期作为 PK
猜你喜欢
  • 2015-10-06
  • 2021-07-11
  • 2011-08-10
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 2014-10-20
  • 1970-01-01
相关资源
最近更新 更多