2015-04-02 255 views
0

我想要做的是汇总来自所有租户/用户的所有数据,并从那里创建SQL视图。然而,租户的创建是动态创建的,但放心,他们的所有表都是相同的。Postgresql使用结果集作为查询的值

我想在这里做的是首先让我的数据库中的所有租户使用此查询。

select distinct table_schema 
from information_schema.tables 
where table_schema not in ('pg_catalog', 'information_schema','public') 
and table_schema not like 'pg_toast%' 

我想要做的是为每一行,我会做一个工会。

像这样

(SELECT * FROM tenant1.ref_product) 
UNION ALL(SELECT * FROM tenant2.ref_product) 
UNION ALL(SELECT * FROM tenant3.ref_product) 

这可能吗?

+0

我希望'table_schema'会返回'tenant1,tenant2,tenant3',对吗? – 2015-04-02 09:36:34

+0

@unique_id yup。它会返回它。 – user962206 2015-04-02 09:39:34

+0

只显示表'ref_product'的结构(创建脚本)? – 2015-04-02 09:51:52

回答

2

你不能这样做,在一个命令,你需要首先执行一个打造你想要的SELECT声明,并复制它的结果,并执行它:

SELECT string_agg(
    format('(SELECT * FROM %I.ref_product)', nspname), 
      ' UNION ALL ') 
FROM pg_namespace 
WHERE nspname !~ '^(pg_.*|information_schema|public)$'; 

另一种选择是使用PL/pgSQL的EXECUTE命令,例如:

CREATE OR REPLACE FUNCTION ref_product() 
RETURNS SETOF tenant1.ref_product 
LANGUAGE plpgsql STABLE AS $$ 
DECLARE 
    v_cmd text; 
BEGIN 
    SELECT string_agg(
     format('(SELECT * FROM %I.ref_product)', nspname), 
       ' UNION ALL ') 
    INTO v_cmd 
    FROM pg_namespace 
    WHERE nspname !~ '^(pg_.*|information_schema|public)$' 
    RETURN QUERY EXECUTE v_cmd; 
END; 
$$; 

最后,如果你经常使用这一点,考虑创建另一个模式(让我们说“tenant_all”)使用相同的表定义,并设置所有其它表作为儿童它使用PostgreSQL的INHERTIS。例如:

CREATE SCHEMA tenant_all; 
CREATE TABLE tenant_all.ref_product(LIKE tenant1.ref_product); 
ALTER TABLE tenant1.ref_product INHERIT (tenant_all.ref_product); 
ALTER TABLE tenant2.ref_product INHERIT (tenant_all.ref_product); 
ALTER TABLE tenant3.ref_product INHERIT (tenant_all.ref_product); 
... 
ALTER TABLE tenantN.ref_product INHERIT (tenant_all.ref_product); 

所以这样你可以简单的查询tennat_all.ref_product,它会工作完全一样,如果要查询其一个与UNION ALL追加。

当然,在所有情况下,我假设表格模式匹配完美。

+0

在你的第三个例子。如果tenant3有新的产品。它会立即反映tenant_all吗? – user962206 2015-05-11 06:49:56

+0

做更新级联?我想要做的是将来自不同租户的所有数据汇总到一个视图/来源 – user962206 2015-05-11 06:50:16

+0

@ user962206,正如我所说的那样,它将完全按照使用“UNION ALL”查询每个数据的方式工作。这就是继承在PostgreSQL中的工作方式。当你查询父级(例如'FROM master')就像拥有它并附加了所有子级(例如'FROM(SELECT * FROM ONLY(master)UNION ALL SELECT * FROM child1 UNION ALL SELECT * FROM child2 ...)AS master'的)。所以是的,通过查询“tenant_all”可以看到对“tenant *”的任何修改。只要确保仅对“tenant_all”执行DDL更改,或者至少保持更改同步。 – MatheusOl 2015-05-11 19:24:18