我试着按照这个答案
Dynamic UNION ALL query in Postgres
但我得到了 错误:语法错误处于或接近"记录"
DECLARE
rec record;
strSQL text;
BEGIN
FOR
rec in
select table_name
from
information_schema.tables
where
table_name like 'history%'
loop
strSQL : = strSQL || 'Select * from' || rec.table_schema ||'.'|| rec.table_name || ' UNION ';
end loop;
-- remove last ' UNION ' from strSQL
--strSQL := 'Select row_number() over(order by rowid ) as row_num from (' || strSQL || ')';
execute strSQL;
有人有什么想法吗?
背景: 历史表每晚移动到其自己的表,并附加日期。
所以每个表名的history04242018,有什么更好的方法来获取多天的数据?
编辑:表格总是具有相同数量的列,因此联合应该没问题
edit2:我只有读取权限。
更新 建议使用匿名代码块我现在使用以下内容:
DO
$$
declare
strSQL text;
begin
select
string_agg(format('select * from %I.%I', table_schema, table_name), E' union\n')
into strSQL
from information_schema.tables
where table_name like 'history%';
execute strSQL ;
end $$;
然而我现在得到错误
描述错误:无法检索EXPLAIN计划:错误:语法 错误在或附近" DO"职位:58
0记录影响
答案 0 :(得分:3)
declare
,for
,loop
,execute
是plpgsql
的一部分,不是普通的sql
(declare
可以在普通sql
中使用但具有不同含义)。因此,如果要从中返回一些数据,则应将代码包装到anonymous block或function中:
create function get_history(p_day int)
returns table (<structure of history tables here>)
-- or
-- returns setof <history table name>
language plpgsql
as $$
declare
strSQL text;
begin
select
string_agg(format('select * from %I.%I', table_schema, table_name), E' union\n')
into strSQL
from information_schema.tables
where table_name like to_char(p_day, '"history__"FM09%');
return query execute strSQL;
end $$;
另请查看Table partitioning(在文章顶部选择您的PostgreSQL版本)。
<强>更新强>
但是,有几种方法可以在不更改数据库架构的情况下从匿名plpgsql块返回查询数据:cursors和prepared statements。
IMO第二个更简单,所以:
do $$
declare
strSQL text;
begin
select
string_agg(format('select * from %I.%I', table_schema, table_name), E' union\n')
into strSQL
from information_schema.tables
where table_name like to_char(p_day, '"history__"FM09%');
-- Prepend "prepare", change the "foo" name as you wish
strSQL := 'prepare foo as ' || strSQL;
execute strSQL;
end $$;
-- Usage
execute foo;
-- And deallocate prepared statement when it does not need anymore:
deallocate foo;