触发功能,用于在INSERT上更新列

问题描述 投票:0回答:2

我想为postgresql表设置一个触发器函数,该表应该使用从另一列派生的数据更新列。

表:

CREATE TABLE day (
symbol varchar(20) REFERENCES another_table(symbol),
date date,
open NUMERIC(8,2),
high NUMERIC(8,2),
low  NUMERIC(8,2),
close NUMERIC(8,2),
sma8 NUMERIC(8,2),
PRIMARY KEY(symbol, date));

注意:复合主键。

示例INSERT:

INSERT INTO day VALUES('ABC', '2019-03-19', 102.3, 110.0, 125.3, 120.4, 0);
INSERT INTO day VALUES('ABC', '2019-03-20', 112.3, 109.0, 119.3, 118.4, 0);
INSERT INTO day VALUES('DEF', '2019-03-19', 1112.3, 1100.0, 1155.3, 1120.4, 0);
INSERT INTO day VALUES('DEF', '2019-03-20', 1202.3, 1180.0, 1205.3, 1190.4, 0);

等等。

当'date'列是唯一的主键并且该表仅包含与一个'符号'有关的数据时(即该表包含各个唯一日期上一个特定符号的数据),以下触发器功能正常工作。

create or replace function update_sma8() RETURNS TRIGGER AS
$$
 BEGIN

 UPDATE day d SET sma8 = s.simple_mov_avg 
 FROM
 (
  SELECT  sec.date,AVG(sec.close)  
    OVER(ORDER BY sec.date ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) AS 
     simple_mov_avg FROM day sec
 )s where s.date = NEW.date  --The newly inserted date
      AND d.date = s.date;   
 RETURN NULL;

 END $$ language plpgsql;

参考:SQL trigger function to UPDATE daily moving average upon INSERT

我想更新'sma8'列,其值是通过平均当前'close'值和一个特定符号的最后7'close'值得出的值('date'变化,即过去的数据)。同样适用于其他符号。

请指导我。谢谢。

sql postgresql
2个回答
0
投票

您需要知道如何按“符号”过滤行。

  1. 添加WHERE子句进行过滤。
WHERE sec.symbol = NEW.symbol
  1. 然后,您注册触发器。
CREATE TRIGGER day_insert
    AFTER INSERT ON day
    FOR EACH ROW
    EXECUTE PROCEDURE update_sma8();
  1. 确保插入行时将更新“sma8”列。

这是完整的代码。


DROP FUNCTION public.update_sma8();

CREATE FUNCTION public.update_sma8()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF 
AS $BODY$
 BEGIN

 UPDATE day d SET sma8 = s.simple_mov_avg 
 FROM
 (
  SELECT  sec.date,AVG(sec.close)  
    OVER(ORDER BY sec.date ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) AS 
     simple_mov_avg FROM day sec WHERE symbol = NEW.symbol
 )s where s.date = NEW.date  --The newly inserted date
      AND d.date = s.date ;   
 RETURN NULL;

 END $BODY$;

ALTER FUNCTION public.update_sma8()
    OWNER TO postgres;

0
投票

您可以添加PARTITION BY symbol,然后在where子句中使用它来计算每个符号。

create or replace function update_sma8() RETURNS TRIGGER AS
$$
 BEGIN

 UPDATE day d SET sma8 = s.simple_mov_avg 
 FROM
 (
  SELECT  sec.date,sec.symbol,AVG(sec.close)  
    OVER( partition by symbol ORDER BY sec.date ROWS BETWEEN 
                          7 PRECEDING AND CURRENT ROW) AS 
     simple_mov_avg FROM day sec
 )s where s.date = NEW.date  --The newly inserted date
      AND d.date = s.date   
      AND d.symbol = s.symbol;
  RETURN NULL;
 END $$ language plpgsql;

DEMO

© www.soinside.com 2019 - 2024. All rights reserved.