繁体   English   中英

Postgres中的动态UNION ALL查询

[英]Dynamic UNION ALL query in Postgres

我们正在使用Postgres / PostGis连接来获取通过地理服务器发布的数据。

目前查询看起来像这样:

SELECT 
    row_number() over (ORDER BY a.ogc_fid) AS qid, a.wkb_geometry AS geometry
FROM
(
   SELECT * FROM test
   UNION ALL
   SELECT * FROM test1
   UNION ALL
   SELECT * FROM test2
)a

在我们的数据库中,仅将有效的shapefile导入到单个表中,因此使UNION ALL零件动态化(遍历每个表并执行UNION ALL语句)是有意义的。 有没有一种方法可以以标准的Postgres方式执行此操作,或者我需要编写一个函数,语法看起来如何? 我对SQL很陌生。

shapefile具有不同的数据结构,并且只有ogc_fid列和wkb_geometry列始终可用,我们希望从数据库中合并所有表。

这只是一般性准则,您需要在细节(特别是语法)方面进行工作。

您需要创建一个存储过程

创建一个循环,检查所需information_schema.tables的表名的information_schema.tables过滤器

DECLARE    
    rec record;
    strSQL text;
BEGIN

然后为每个表创建一个strSQL

 FOR rec IN SELECT table_schema, table_name
            FROM information_schema.tables                
 LOOP
     strSQL := strSQL || 'SELECT ogc_fid, wkb_geometry FROM ' || 
               rec.table_schema || '.' || rec.table_name || ' UNION ';
 END LOOP;

-- have to remove the last ' UNION ' from strSQL    

strSQL := 'SELECT  row_number() over (ORDER BY a.ogc_fid) AS qid,
         a.wkb_geometry AS geometry FROM (' || strSQL || ')';

EXECUTE strSQL;

一种解决方案是使用row_to_json()将其余的列序列化为json (自PostgreSQL9.2起可用)。 对于PG9.1(及更低版本),您可以使用hstore ,但请注意,所有值都强制转换为文本。

为什么要序列化? 这是不可能的工会行,其中柱的侧向承载力的数量而变化,或数据类型不工会查询之间的匹配。

我创建了一个简单的示例来说明:

--DROP SCHEMA testschema CASCADE;
CREATE SCHEMA testschema;

CREATE TABLE testschema.test1 (
    id integer,
    fid integer,
    metadata text
);

CREATE TABLE testschema.test2 (
    id integer,
    fid integer,
    city text,
    count integer
);

CREATE TABLE testschema.test3 (
    id integer,
    fid integer
);


INSERT INTO testschema.test1 VALUES (1,   4450, 'lala');
INSERT INTO testschema.test2 VALUES (33,  6682, 'London', 12345);
INSERT INTO testschema.test3 VALUES (185, 8991);


SELECT 
    row_number() OVER (ORDER BY a.fid) AS qid, a.*
FROM
(
    SELECT id, fid, row_to_json(t.*) AS jsondoc FROM testschema.test1 t
    UNION ALL 
    SELECT id, fid, row_to_json(t.*) AS jsondoc FROM testschema.test2 t
    UNION ALL 
    SELECT id, fid, row_to_json(t.*) AS jsondoc FROM testschema.test3 t    
) a

SELECT输出:

qid  id    fid    jsondoc
1;   1;    4450;  "{"id":1,"fid":4450,"metadata":"lala"}"
2;   33;   6682;  "{"id":33,"fid":6682,"city":"London","count":12345}"
3;   185;  8991;  "{"id":185,"fid":8991}"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM