【问题标题】:Updating average rating on new table entry with a trigger使用触发器更新新表条目的平均评分
【发布时间】:2022-01-09 09:52:19
【问题描述】:

每次在监视表中插入一个新元组时,我都会尝试计算新的平均值(在电影表中) 我想过在触发器中创建一个新表,创建一个 for 循环来计算平均值以及声明一个新的表变量,这些都不适合我

这是我目前拥有的

    Create OR REPLACE TRIGGER new_avg
    FOR INSERT ON WATCH
    COMPOUND TRIGGER
        avg_c   REAL;
        counter INTEGER :=0;
    BEFORE EACH ROW IS
    BEGIN

        SELECT AVG(rating) INTO avg_c FROM ??? WHERE :NEW.movie_ID = movie_ID;
    END BEFORE EACH ROW;
    AFTER EACH ROW IS 
    BEGIN
        UPDATE Movie SET avg_rating = avg_c WHERE :NEW.movie_ID = movie_ID;
    END AFTER EACH ROW;
END;
/

关于如何让它工作的任何想法?

【问题讨论】:

  • 停下来,只是不要。数据应保持无冗余以避免出现不一致的可能性。因此,将一张表的平均值写入另一张表并不是一件好事。如果你需要平均值,你可以随时查询它并得到正确的结果。为方便起见,您可以创建一个存储此类查询的视图,这样您就不必每次都重复它。
  • 感谢您为我提供通常的 stackoverflow 答案,但是,我需要使用触发器更新平均值。有关如何做到这一点的任何信息?

标签: sql oracle11g


【解决方案1】:

不要这样做;根据需要使用视图或查询。


但是,作为一项学术活动。创建可用于 SQL 查询的类型:

CREATE TYPE id_list IS TABLE OF INTEGER;

然后跟踪更新的电影,然后在语句完成更新所有带有评分的电影之后:

Create OR REPLACE TRIGGER new_avg
FOR INSERT ON WATCH
COMPOUND TRIGGER
  movies id_list := id_list();
AFTER EACH ROW
IS
BEGIN
  movies.EXTEND;
  movies(movies.COUNT) := :NEW.movie_id;
END AFTER EACH ROW;
AFTER STATEMENT
IS 
BEGIN
  MERGE INTO Movie dst
  USING (
    SELECT movie_id,
           AVG(rating) AS rating
    FROM   watch
    WHERE  movie_id MEMBER OF movies
    GROUP BY movie_id
  ) src
  ON (dst.movie_id = src.movie_id)
  WHEN MATCHED THEN
    UPDATE
    SET avg_rating = src.rating;
END AFTER STATEMENT;
END;
/

db小提琴here

【讨论】:

    猜你喜欢
    • 2020-03-20
    • 2014-05-23
    • 1970-01-01
    • 2020-07-15
    • 2021-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多