如何在postgres函数中创建临时表

时间:2019-04-05 00:46:49

标签: postgresql

这里的问题是,当我转到代码的UPDATE块时,我不再可以访问子查询中的数据

我尝试了创建临时表和从Deleted_rows中进行选择的多种变体,而不是WITH语句的子查询AS的一部分,但它不喜欢我尝试过的任何方法,尤其不喜欢我尝试创建表在初始with子句之后

CREATE OR REPLACE FUNCTION public.aggregate_userviews(
    )
    RETURNS text
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE 
AS $BODY$BEGIN

WITH deleted_rows AS (
    DELETE FROM user_details_views 
    WHERE ts < (timezone('UTC', now() - interval '5 minutes')) RETURNING *
), subquery AS (SELECT DISTINCT username, DATE(ts) as day_of_month, COUNT(id) AS user_views
        FROM deleted_rows
        GROUP BY username, day_of_month
        ORDER BY day_of_month ASC)

INSERT INTO analytics_summary ( username, day_of_month, user_views)
    SELECT username, day_of_month, user_views
    FROM subquery           
ON CONFLICT (username ,day_of_month)
DO UPDATE SET user_views = analytics_summary.user_views + excluded.user_views;

UPDATE user_details u
    SET view_count = u.view_count + subquery.user_views
    FROM subquery
    WHERE u.username=subquery.username;

RETURN NULL;
END;$BODY$;

如果我删除了update语句,它可以很好地工作,并且我可能可以使用触发器来进行更新,但是如果我与现有解决方案相距不远,我宁愿不这样做

1 个答案:

答案 0 :(得分:2)

知道了,我必须在WITH上方创建表,然后在第一次插入之前将其填充,然后将temp表用于以下两个代码块,例如

CREATE OR REPLACE FUNCTION public.aggregate_userviews(
    )
    RETURNS text
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE 
AS $BODY$BEGIN

create temporary table temp_userviews_table (username varchar, day_of_month date, user_views int);

WITH deleted_rows AS (
    DELETE FROM user_details_views 
    WHERE ts < (timezone('UTC', now() - interval '5 minutes')) RETURNING *
), subquery AS (SELECT DISTINCT username, DATE(ts) as day_of_month, COUNT(id) AS user_views
        FROM deleted_rows
        GROUP BY username, day_of_month
        ORDER BY day_of_month ASC)

INSERT INTO temp_userviews_table (username, day_of_month, user_views)
    SELECT username, day_of_month, user_views
    FROM subquery;

INSERT INTO analytics_summary ( username, day_of_month, user_views)
    SELECT username, day_of_month, user_views
    FROM temp_userviews_table           
ON CONFLICT (username ,day_of_month)
DO UPDATE SET user_views = analytics_summary.user_views + excluded.user_views;

UPDATE user_details u
    SET view_count = u.view_count + temp_userviews_table.user_views
    FROM temp_userviews_table
    WHERE u.username=temp_userviews_table.username;

drop table temp_userviews_table;
RETURN NULL;
END;$BODY$;