我有一个存储了许多带边界的“区域”的PostgreSQL 9.1数据库,我需要计算出每个区域的有效边界。其中一些区域直接存储边界(作为PostGIS几何体),而其他区域由多个子区域组成,需要将它们聚合在一起。
对于每个子区域,都有一个“操作”,确定它是添加到前一个区域还是从中减去或与其相交。这意味着顺序也很重要,因此需要一个序列号。
我有一个聚合函数可以解决这个问题,但问题是结构是递归的 - 子区域本身可能由子区域组成。
一个简化的模式:
对于每个子区域,都有一个“操作”,确定它是添加到前一个区域还是从中减去或与其相交。这意味着顺序也很重要,因此需要一个序列号。
我有一个聚合函数可以解决这个问题,但问题是结构是递归的 - 子区域本身可能由子区域组成。
一个简化的模式:
CREATE TABLE area
(id integer NOT NULL
, border geometry NULL
);
CREATE TABLE area_part
(parent_area_id integer NOT NULL
, sequence integer NOT NULL
, operation text NOT NULL
, child_area_id integer NOT NULL
);
聚合函数签名(它期望按sequence
排序的行):
CREATE AGGREGATE aggregate_geometry(area geometry, operation text)
-- RETURNS geometry
我创建了一个普通的PL/pgSQL函数,它可以递归调用自身并且可以正常工作,但是由于它执行了许多子查询,所以速度很慢。有什么更有效率的方法吗?
我还尝试使用递归CTE编写查询:
WITH RECURSIVE area_rec AS
(
SELECT *
FROM area
WHERE id = the_if_of_interest
UNION ALL
SELECT c.*
FROM area_rec rec
JOIN area_part p ON rec.id = p.parent_area_id
JOIN area c ON p.child_area_id = c.id
)
SELECT *
FROM area_rec
这对于返回给定区域所需的所有行来说是可以的,但我不知道如何将这些值插入到我的聚合函数中。我需要某种“聚合递归函数”!
ST_Union
。实际函数更复杂,使用了一些与问题无直接关联的其他内容,但它接受一组几何对象并返回一个几何对象,就像聚合版本的ST_Union
一样。 - undefined