我在PostgreSQL中有非常复杂的查询,它会联合几个表,这些表都有我们想要联合的通用字段集。目前我们正在预生成此查询。我已经看到使用UNPIVOT解决这个问题了,我想知道是否可以在PostgreSQL的SQL风格中做到这一点。
我所拥有的是像
SELECT a,b,c FROM a UNION ALL
SELECT a,b,c FROM c UNION ALL
SELECT a,b,c FROM d UNION ALL
SELECT a,b,c FROM e UNION ALL
SELECT a,b,c FROM f
我想在单独的表中将表的名称联合起来并将其用于此查询。
PS。更改架构不是一种选择。
答案 0 :(得分:3)
对inheritance的Postgres文档使用继承。您需要重新创建数据库,但如果您在没有模式的情况下转储表,使用继承创建新模式并重新加载数据,这很容易。
架构看起来像这样:
CREATE TABLE base (a, b, c);
CREATE TABLE a () INHERITS (base);
CREATE TABLE b () INHERITS (base);
....
使用此设计,您可以进行简单的选择:
SELECT * FROM base;
这将返回base
中的所有行以及继承自base
的所有表。
如果您还没有这样做,请从文档中了解PostgreSQL表partitioning。
答案 1 :(得分:2)
如果你真的无法修复你的设计(或者不想使用jmz的非常好的建议),你唯一的选择可能是一个返回功能,可以“动态”构建必要的UNION然后返回结果。
create or replace function my_union() returns table(a integer, b integer, c integer) as $body$ declare union_cursor refcursor; table_cursor cursor for SELECT table_name FROM union_source; union_query text := ''; begin -- build the query string for the union for table_list_record in table_cursor loop if union_query '' then union_query := union_query||' UNION ALL'; end if; union_query := union_query||' SELECT a,b,c FROM '||table_list_record.table_name; end loop; -- run the union and return the result for a,b,c IN EXECUTE union_query LOOP return next; end loop; end; $body$ language plpgsql;
该函数根据union_source中的表名构建必要的UNION,然后执行union并返回结果。
如果列不总是具有相同的名称,您可以扩展union_source表以存储每个表的列列表。
要使用此功能,只需从中选择:
select * from my_union()