SQL trigger function to UPDATE daily moving average upon INSERT

前端 未结 2 618
死守一世寂寞
死守一世寂寞 2021-01-25 23:24

I am trying to create a SQL trigger function which should UPDATE a column when data is INSERTed INTO the table. The update is based on the values present in the values being INS

相关标签:
2条回答
  • 2021-01-25 23:42

    Can't you just do something along those lines?

    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
    )
    

    I know very well it could appear complicated compared to a trigger.
    However, I am trying to avoid a case where you successfully create the ON INSERT trigger and next want to handle updates in the table. Updating a table within a procedure triggered by an update in the same table is not the best idea.

    0 讨论(0)
  • 2021-01-25 23:45

    You may do an UPDATE FROM your select query using appropriate joins in your Trigger.

    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;
    

    Demo

    The only caveat of using this method is that if someone deletes a row or updates close column, then the values have to be recalculated, which won't happen for existing rows. Only the inserted row will see the right re-calculated value.

    Instead, you may simply create View to calculate the sma8 column from the main table for all rows when requested.

    0 讨论(0)
提交回复
热议问题