联合多个表

时间:2018-04-24 23:31:50

标签: postgresql

我试着按照这个答案

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记录影响

1 个答案:

答案 0 :(得分:3)

declareforloopexecuteplpgsql的一部分,不是普通的sqldeclare可以在普通sql中使用但具有不同含义)。因此,如果要从中返回一些数据,则应将代码包装到anonymous blockfunction中:

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块返回查询数据:cursorsprepared 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;

Simple working example