我需要创建一个物化视图,以便从pg_tables
循环所有工作列表。
首先,我创建了一个查询,然后尝试创建一个for循环。
这是我的第一个代码没有for循环。
SELECT
count(visit_num) AS total_claim_count,
count(user_id) as assigned_count,
(count(visit_num)-count(user_id)) AS not_assigned_count,
count(case when doe <= (SELECT doe - INTERVAL '30 days') and user_id is not null then 1 end ) AS Assigned_Last_30_Days,
(count(user_id)-count(case when doe <= (SELECT doe - INTERVAL '30 days') and user_id is not null then 1 end )) AS not_Assigned_last_30_days,
count(case when doe >= (SELECT doe - INTERVAL '30 days') and user_id is not null then 1 end ) AS Assigned_before_30_Days,
count(case when doe > (SELECT doe - INTERVAL '30 days') and user_id is null then 1 end ) AS not_Assigned_before_30_days,
count(CASE WHEN date_worked is not null then 1 end) followed_up,
count(CASE WHEN last_denied_date is not null then 1 end) denials,
count(case when status_and_action_code='No Status - Need to follow-up' then 1 end) AS no_status
FROM Worklist_123456
这是代码与循环我尝试。但它是行不通的。
DO $$
DECLARE
pg_tables varchar(1000000);
tbl_name record;
tablename varchar(1000000);
begin
For tbl_name IN SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND tablename LIKE 'worklist¥_%' ESCAPE '¥'
loop
tablename := tbl_name.tablename;
SELECT
count(visit_num) AS total_claim_count,
count(user_id) as assigned_count,
(count(visit_num)-count(user_id)) AS not_assigned_count,
count(case when doe <= (SELECT doe - INTERVAL '30 days') and user_id is not null then 1 end ) AS Assigned_Last_30_Days,
(count(user_id)-count(case when doe <= (SELECT doe - INTERVAL '30 days') and user_id is not null then 1 end )) AS not_Assigned_last_30_days,
count(case when doe >= (SELECT doe - INTERVAL '30 days') and user_id is not null then 1 end ) AS Assigned_before_30_Days,
count(case when doe > (SELECT doe - INTERVAL '30 days') and user_id is null then 1 end ) AS not_Assigned_before_30_days,
count(CASE WHEN date_worked is not null then 1 end) followed_up,
count(CASE WHEN last_denied_date is not null then 1 end) denials,
count(case when status_and_action_code='No Status - Need to follow-up' then 1 end) AS no_status
FROM tablename;
END LOOP;
END; $$;
它给出了这样的错误。
ERROR: column reference "tablename" is ambiguous
LINE 1: SELECT tablename FROM pg_tables WHERE schemaname = 'public' ...
^
DETAIL: It could refer to either a PL/pgSQL variable or a table column.
QUERY: SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND tablename LIKE 'worklist¥_%' ESCAPE '¥'
CONTEXT: PL/pgSQL function inline_code_block line 9 at FOR over SELECT rows
SQL state: 42702
任何人都可以帮助我解决这个问题。谢谢。
2条答案
按热度按时间bjg7j2ky1#
正如@Frank Heikens所指出的,您是在用动态SQL术语思考问题:demo
count(case...)
正在模拟聚合FILTER
子句。doe>=(SELECT doe-INTERVAL '30 days')
没有什么意义,你要检查的是这个值是否大于它自己,或者说是减小了,这实际上就是some_number>=(some_number-1)
。count(arg)
不计算arg
为空的行:count ( "any" ) → bigint
计算输入值不为空的输入行数。count(case when arg is not null then 1 end)
与count(arg)
相同,count(case when (condition) and arg is not null then 1 end)
与count(arg)filter(where (condition))
相同。您可能需要重新考虑在何处以及为什么使用
count(arg)
,而不是使用count(*)
和count(case when arg is not null then 1 end)
。pgky5nke2#
∮ ∮ ∮ ∮
发布alternative解决方案separately,以演示来自@Frank Heikens的其他建议。
您通常会选择一个预先存在的特性来区分分区,比如给定分区应该包含的日期范围、数据源位置标识符、用户组。我添加一个虚拟列作为键,只是为了说明这个想法:demo
然后,您的循环变成了主集合聚合表上的简单
group by
: