我正在尝试创建一个SQL触发函数,当将数据插入表中时,该函数应该更新列。更新是基于要插入的值中显示的值。
我有下表存储股票的每日OHLC数据。
CREATE TABLE daily_ohlc (
cdate date,
open numeric(8,2),
high numeric(8,2),
low numeric(8,2),
close numeric(8,2),
sma8 numeric(8,2)
);
INSERT命令:
INSERT INTO daily_ohlc (cdate, open, high, low, close)
values ('SYMBOL', 101, 110, 95, 108);
执行此命令后,我想基于当前值“ INSERTed”和表中已有的值来更新“ sma8”列。
到目前为止,我正在使用以下SQL查询来计算每一行的值,然后使用结果使用python更新“ sma8”列。
SELECT sec.date, AVG(sec.close)
OVER(ORDER BY sec.date ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) AS
simple_mov_avg FROM daily_ohlc sec;
上面的查询计算最近8条记录(包括当前行)的简单移动平均值。
使用此过程,每次插入数据时,都会更新“ sma8”列中的每一行数据。我想通过使用触发器仅更新最后一行(即正在插入的行)。该怎么做?
答案 0 :(得分:0)
您不能只是按照这些原则做些什么吗?
INSERT INTO daily_ohlc
SELECT current_date, 101, 110, 95, 108, (COUNT(*)*AVG(close)+108)/(1+Count(*))
FROM daily_ohlc
WHERE cDate >= ANY (
SELECT MIN(cdate)
FROM (SELECT CDate, ROW_NUMBER() OVER (ORDER BY CDate DESC) as RowNum FROM daily_ohlc) a
WHERE RowNum <= 7
)
我很清楚,与触发器相比,它看起来可能很复杂。
但是,我试图避免您成功创建ON INSERT
触发器并且接下来要处理表中的更新的情况。在同一张表中的更新触发的过程中更新表不是最好的主意。
答案 1 :(得分:0)
您可以在触发器中使用适当的联接来进行UPDATE FROM
选择查询。
create or replace function update_sma8() RETURNS TRIGGER AS
$$
BEGIN
UPDATE daily_ohlc d SET sma8 = s.simple_mov_avg
FROM
(
SELECT sec.cdate,AVG(sec.close)
OVER(ORDER BY sec.cdate ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) AS
simple_mov_avg FROM daily_ohlc sec
)s where s.cdate = NEW.cdate --The newly inserted cdate
AND d.cdate = s.cdate;
RETURN NULL;
END $$ language plpgsql;
使用此方法的唯一警告是,如果某人删除行或更新 close
列,则必须重新计算值,这将赢得现有行不会发生。只有插入的行会看到正确的重新计算值。
相反,您可以简单地创建View
来在需要时从主表为所有行计算sma8
列。