这里的问题是,当我转到代码的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语句,它可以很好地工作,并且我可能可以使用触发器来进行更新,但是如果我与现有解决方案相距不远,我宁愿不这样做
答案 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$;