【问题标题】:Union multiple tables联合多个表
【发布时间】:2018-04-26 02:27:03
【问题描述】:

我试图遵循这个答案

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

【问题讨论】:

  • 以下是如何使用单个查询构建动态语句: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%';
  • @Abelisto 我可以在没有“进入”工作的情况下获得第一部分 - 不太确定我应该如何处理其余部分。
  • 我的回答第二行You need create a store procedure
  • @JuanCarlosOropeza 只读环境

标签: postgresql


【解决方案1】:

declare,for,loop,executeplpgsql的部分,不是普通的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

【讨论】:

  • 谢谢你,不过我只有只读,不能做函数。
  • 更新了原始问题 - 仍然出现错误
  • @lookslikeanevo 已针对只读环境更新答案。见Simple working example
  • Abellisto - 与我的更新相同的错误 - 甚至尝试了 sqlfiddle 中的示例和相同的错误
  • @lookslikeanevo 正如我在问题下的最后一条评论中所说:似乎是框架的问题。如您所见,它适用于纯数据库连接。所以更具体一点:你用什么来连接数据库和执行查询?
猜你喜欢
  • 1970-01-01
  • 2020-11-17
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多