Postgres 9.1 - 我有一个模式,按月“分区”表(每个月创建一个新表,所有列都相同)。它未设置为具有“主”表的正常分区。我目前正在编写一个相当大的查询,我每个月都要运行几次。
架构:augmented_events
表:
p201301
(2013年1月)
p201302
(2013年2月)
p201303
(2013年3月)
...
p201312
(2013年12月)
p201401
(2014年1月)
现在我必须将我的(简化)查询编写为:
select *
from augmented_events.p201301
union
select *
from augmented_events.p201302
union
select *
from augmented_events.p201303
union
select *
from augmented_events.p201312
union
select *
from augmented_events.p201401
每个月我都需要在新月加入。我想让它更具可扩展性,而不必每个月重新访问它。是否有一个我可以创建的函数(或者一个存在的函数)循环遍历augmented_events
模式中的每个表,并将其视为我将这些表联合起来?
答案 0 :(得分:0)
我怀疑在直接SQL中可能有这样的东西,但你可以使用外部代码(PHP,Perl,.NET;你熟悉的任何东西)。它将查询模式,删除旧视图,并创建新模式。安排它每天运行,你将能够使用视图而不考虑包含哪些表。
这是一个创可贴:更好的方法是纠正这种伪分区。
答案 1 :(得分:0)
...将通过INHERITANCE
进行分区。实际上它很简单。考虑这个相关的答案:
Select (retrieve) all records from multiple schemas using Postgres
虽然您遇到了不幸的设计,但您可以在EXECUTE
的plpgsql函数中使用动态SQL。
创建此功能一次:
CREATE OR REPLACE FUNCTION f_all_in_schema_foo()
RETURNS SETOF t AS
$func$
BEGIN
RETURN QUERY EXECUTE (
SELECT string_agg(format('SELECT * FROM %s', c.oid ::regclass)
,E'\nUNION ALL\n'
ORDER BY relname)
FROM pg_namespace n
JOIN pg_class c ON c.relnamespace = n.oid
WHERE n.nspname = 'foo'
AND c.relkind = 'r'
);
END
$func$ LANGUAGE plpgsql;
请注意我如何小心避免 SQL注入的任何可能性(表名必须被视为“用户输入”!)。在这个相关答案中考虑详细的建议:
Table name as a PostgreSQL function parameter
生成并执行以下形式的查询:
SELECT * FROM foo.p201301
UNION ALL
SELECT * FROM foo.p201302
UNION ALL
SELECT * FROM foo.p201303
UNION ALL
...
由于string_agg()
中的ORDER BY子句,表按名称排序。
您可以像表一样使用此表函数。拨打:
SELECT * FROM f_all_in_schema_foo();
表现应该不错。
您可以在SO with this search找到类似的解释和链接示例。