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 将被导入到单个 table 中,因此使 UNION ALL 部分动态化(循环每个 table 并制作 UNION ALL 语句是有意义的).有没有办法以标准的 Postgres 方式执行此操作,或者我是否需要编写一个函数以及语法是什么样的?我对 SQL 很陌生。
shapefile 具有不同的数据结构,只有 ogc_fid 列和 wkb_geometry 列始终可用,我们想合并数据库中的所有 table。
这只是一般准则,您需要在细节方面特别是语法方面进行工作。
您需要创建一个存储过程
为table你想要的名字
创建一个循环检查information_schema.tables
过滤器
DECLARE
rec record;
strSQL text;
BEGIN
然后用每个 table
创建一个 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;
一种解决方案是将其余列序列化为 json with row_to_json()。 (自 PostgreSQL9.2 起可用)。
对于 PG9.1(及更早版本),您可以使用 hstore,但请注意,所有值都将转换为文本。
为什么要连载?无法 union 列数不同的行,或者联合查询之间的数据类型不匹配。
我创建了一个快速示例来说明:
--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}"
我们正在使用 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 将被导入到单个 table 中,因此使 UNION ALL 部分动态化(循环每个 table 并制作 UNION ALL 语句是有意义的).有没有办法以标准的 Postgres 方式执行此操作,或者我是否需要编写一个函数以及语法是什么样的?我对 SQL 很陌生。
shapefile 具有不同的数据结构,只有 ogc_fid 列和 wkb_geometry 列始终可用,我们想合并数据库中的所有 table。
这只是一般准则,您需要在细节方面特别是语法方面进行工作。
您需要创建一个存储过程
为table你想要的名字
创建一个循环检查information_schema.tables
过滤器
DECLARE
rec record;
strSQL text;
BEGIN
然后用每个 table
创建一个 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;
一种解决方案是将其余列序列化为 json with row_to_json()。 (自 PostgreSQL9.2 起可用)。 对于 PG9.1(及更早版本),您可以使用 hstore,但请注意,所有值都将转换为文本。
为什么要连载?无法 union 列数不同的行,或者联合查询之间的数据类型不匹配。
我创建了一个快速示例来说明:
--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}"