Postgresql使用Result set作为查询值

时间:2015-04-02 09:23:23

标签: sql postgresql

我要做的是聚合来自所有租户/用户的所有数据,并从那里创建一个SQL视图。然而,租户的创建是动态创建的,但是放心,所有的表都是相同的。

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

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)
这可能吗?

1 个答案:

答案 0 :(得分: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的内容一样。

当然,在所有情况下,我都假设表格架构完全匹配。