我的桌子上有一些代表建筑物的点:
CREATE TABLE buildings(
pk serial NOT NULL,
geom geometry(Point,4326),
height double precision,
area double precision,
perimeter double precision
)
另一张包含折线的表(大多数已关闭):
CREATE TABLE regions
(
pk serial NOT NULL,
geom geometry(Polygon,4326)
)
我想:
添加两个新列:
ALTER TABLE regions ADD COLUMN buildings_n integer;
ALTER TABLE regions ADD COLUMN area_avg double precision;
如何进行这两项查询?
我已经尝试过第1点,但它失败了:
INSERT INTO regions (buildings_n)
SELECT count(b.geom)
FROM regions a, buildings b
WHERE st_contains(a.geom,b.geom);
谢谢,
斯特凡诺
答案 0 :(得分:0)
你遇到的第一个问题是ST_Contains带有'折线'或者线条只能找到线串的几何上的点。如果你想要一个由线串表示的区域内的点,它就不会起作用,特别是如果它们没有关闭的话。请参阅此处的有效ST_Contains关系示例: http://www.postgis.org/docs/ST_Contains.html
要使空间关系起作用,您必须事先或在查询中动态地将区域的几何体转换为多边形。例如:
ST_Contains(ST_MakePolygon(a.geom),b.geom)
有关详细信息,请参阅此参考: http://www.postgis.org/docs/ST_MakePolygon.html
第二个问题是,要对建筑物表(而不是整个表)的子集使用聚合函数计数或平均值,您需要将区域ID与每个建筑物相关联...
SELECT a.pk region_pk, b.pk building_pk, b.area
FROM regions a, buildings b
WHERE ST_Contains(ST_MakePolygon(a.geom),b.geom)
..然后按照他们所属的地区对您的建筑数据进行分组:
SELECT region_pk, count(), avg(area) average
FROM joined_regions_and_buildings
GROUP BY region_pk;
第三个问题是您正在使用INSERT向新创建的列添加值。 INSERT用于向表中添加新记录,UPDATE用于更改表中现有记录的值。
因此,上面的所有点合并产生以下查询:
WITH joined_regions_and_buildings AS (
SELECT a.pk region_pk, b.pk building_pk, b.area
FROM regions a, buildings b
WHERE ST_Contains(ST_MakePolygon(a.geom),b.geom)
)
UPDATE regions a
SET buildings_n = b.count, area_avg = b.average
FROM (
SELECT region_pk, count(), avg(area) average
FROM joined_regions_and_buildings
GROUP BY region_pk
) b
WHERE a.pk = b.region_pk;