【问题标题】:Postgresql - Union table values from different schemas in a database into one tablePostgresql - 将数据库中不同模式的表值合并到一个表中
【发布时间】:2021-08-09 11:27:41
【问题描述】:

我在 postgres 中有一个名为 Knowledge 的数据库。它有多个模式,每个模式都有相同数量的表,表也有相同的列。 现在我想创建一个名为 Aggregate 的新模式,名为 aggregate.table1 的表,并将来自 schema1.table1 和 schema2.table1 的值放入其中。

  • 我需要在 Aggregate.table1 中添加另一列,其中包含表示模式的值。
  • 如果 schema1.table1 中的任何值被更新,那么 aggregate.table1 应该得到更新的值。

问题, 在 Postgresql 中可以吗?如果是这样,请帮助我。 我需要这个汇总表进行进一步处理

【问题讨论】:

    标签: sql postgresql schema


    【解决方案1】:

    您可以尝试编写anonymous code block 来遍历所有模式和表,以便将数据导入聚合模式。以下块搜索包含在架构s1s2 中的所有表,在架构s_agg 中创建对应的表并最终复制其记录。

    DO $$
    DECLARE row record;
    BEGIN
      FOR row IN SELECT * FROM pg_tables WHERE schemaname IN ('s1','s2') LOOP
        EXECUTE 'CREATE TABLE IF NOT EXISTS s_agg.'||quote_ident(row.tablename)||
          ' AS TABLE ' || quote_ident(row.schemaname)||'.'|| quote_ident(row.tablename) || 
          ' WITH NO DATA;';
        EXECUTE 'INSERT INTO s_agg.' || quote_ident(row.tablename) 
         || ' SELECT * FROM '||quote_ident(row.schemaname)||'.'||quote_ident(row.tablename);
     END LOOP;
    END;
    $$;
    

    演示

    CREATE SCHEMA s1;
    CREATE SCHEMA s2;
    CREATE SCHEMA s_agg;
    
    CREATE TABLE s1.t1 (id int);
    INSERT INTO s1.t1 VALUES (1);
    
    CREATE TABLE s2.t1 (id int);
    INSERT INTO s2.t1 VALUES (42);
            
    DO $$
    DECLARE row record;
    BEGIN
      FOR row IN SELECT * FROM pg_tables WHERE schemaname IN ('s1','s2') LOOP
        EXECUTE 'CREATE TABLE IF NOT EXISTS s_agg.'||quote_ident(row.tablename)||
          ' AS TABLE ' || quote_ident(row.schemaname)||'.'|| quote_ident(row.tablename) || 
          ' WITH NO DATA;';
        EXECUTE 'INSERT INTO s_agg.' || quote_ident(row.tablename) 
         || ' SELECT * FROM '||quote_ident(row.schemaname)||'.'||quote_ident(row.tablename);
     END LOOP;
    END;
    $$;
    
    -- contains values of t1 from s1 and s2
    SELECT * FROM s_agg.t1;
    
     id 
    ----
      1
     42
    

    注意:此代码在聚合架构为空或有空表的假设下工作,否则数据将重复。如果您定期运行它并且表的大小不是太大,您可以在CREATE TABLE 语句之前添加DROP TABLE。要使其适用于所有模式的所有表的每次提交,您必须查看TRIGGERS 甚至logical replication

    【讨论】:

    • @Jim_Jones 我正在寻找一种解决方案,即使 s1.t1 上的增量更新也应该更新 s_agg.t1。我正在寻找 Postgresql 的支持,它会自动执行此操作,而不是定期运行它并清除表。
    • @nandeesh 正如我最后提到的,你需要看看logical replicationtriggers
    • @nandeesh 我发布的代码块是我的旧脚本的一部分,但它应该让您了解如何进行操作和注意事项。另一种选择:您也可以查看pg_agent 并安排一项工作定期为您完成,以防它不需要实时。
    猜你喜欢
    • 2020-08-07
    • 2015-08-28
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2018-06-23
    • 2018-01-08
    • 1970-01-01
    • 2017-06-27
    相关资源
    最近更新 更多