【问题标题】:Loop through like tables in a schema循环遍历模式中的类似表
【发布时间】:2014-01-15 17:42:36
【问题描述】:

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 架构中的每个表,并将其视为合并这些表?

【问题讨论】:

    标签: sql postgresql plpgsql partitioning dynamic-sql


    【解决方案1】:

    适当的解决方案

    ... 将通过inheritance 进行分区。其实很简单。考虑这个相关的答案:

    暂时

    虽然坚持您不幸的设计,但您可以在带有EXECUTE 的 plpgsql 函数中使用动态 SQL。

    创建这个函数一次

    CREATE OR REPLACE FUNCTION f_all_in_schema_foo()
      RETURNS SETOF t
      LANGUAGE plpgsql 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$;
    

    注意我是如何小心避免SQL 注入 的(表名必须被视为“用户输入”!)。见:

    生成并执行表单的查询:

    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 上找到带有解释和链接的类似示例。

    【讨论】:

    • 太好了,感谢您的更新。不要认为现在继承是可行的(我不负责系统,但会与我们的开发团队交谈)。现在,我将使用该功能。
    【解决方案2】:

    我怀疑在直接 SQL 中是否存在类似的情况,但您可以使用外部代码(PHP、Perl、.NET;任何您熟悉的代码)。它将查询架构,删除旧视图并创建新视图。安排它每天运行,您就可以使用该视图,而无需考虑包含哪些表。

    这是一个创可贴:最好是纠正这种伪分区。

    【讨论】:

    • 不幸的是,我们的 DevOps 团队已经设置了这样的表格。我无法改变它。 Erwin 上面有一个解决方案。谢谢。
    猜你喜欢
    • 2019-01-06
    • 2021-11-27
    • 2014-05-16
    • 1970-01-01
    • 2021-11-28
    • 2013-11-13
    • 2016-05-15
    • 1970-01-01
    • 2021-05-10
    相关资源
    最近更新 更多