2

我正在尝试将“基于人口的质心”列添加到一系列美国县多边形,其中位置不是基于多边形的地理质心,而是基于地理名称人口最多的地方的位置人口。例如,我想将箭头指示的点(点直径 = 人口)的几何形状分配给所选多边形的基于人口的质心列:

在此处输入图像描述

我已经测试了这个查询,它为任何给定的多边形(例如波士顿的萨福克县)返回正确的几何图形:

SELECT g1.the_geom
FROM counties c1
JOIN geonames g1
ON ST_Contains(c1.the_geom, g1.the_geom)
WHERE c1.name = 'Suffolk County, MA'
ORDER BY g1.population DESC
LIMIT 1;

但是,我正在处理约 4000 个多边形,当我尝试在这样的 UPDATE 函数中使用查询时,它会无限期地挂起(或者至少比这个数量的特征要长得多):

UPDATE counties
    SET the_geom_popcentroid = (
        SELECT g1.the_geom
        FROM counties c1
        JOIN geonames g1
        ON ST_Contains(c1.the_geom, g1.the_geom)
        ORDER BY g1.population DESC
        LIMIT 1
    );

我在哪里错误地嵌套了这个 UPDATE 函数?

4

2 回答 2

3

仔细检查:由于外部表中的每一行与相关子查询的结果之间没有联系,因此行都有一个常量值。令人费解的是:这不应该很,而是出奇的快。也完全不正确。要修复您的查询:

UPDATE counties c
SET    the_geom_popcentroid = (
        SELECT g.the_geom
        FROM   geonames g
        WHERE  ST_Contains(c.the_geom, g.the_geom)
        ORDER  BY g.population DESC
        LIMIT  1
        );

这会更新所有县。如果一个县根本不应该包含任何地名,the_geom_popcentroid则设置为 NULL。

这个带有JOIN 语法的替代版本只更新至少包含一个地名的县:

UPDATE counties c
SET    the_geom_popcentroid = sub.the_geom
FROM (
    SELECT DISTINCT ON (c1.pk)
           c1.pk, g1.the_geom
    FROM   counties c1
    JOIN   geonames g1 ON ST_Contains(c1.the_geom, g1.the_geom)
    ORDER  BY c1.pk, g1.population DESC
    ) sub
WHERE c.pk = sub.pk;

pk的主键列(或任何唯一列)在哪里counties

解释DISTINCT ON

不确定哪个更快。尝试在两列上使用索引时,ST_Contains()与 with的组合可能会很棘手。测试是否重要。ORDER BY third_column LIMIT nthe_geomEXPLAIN ANALYZE

有时 aLATERAL JOIN可以帮助说服 Postgres 使用索引。相关问题:

于 2014-07-28T16:43:57.903 回答
1

它有助于在这里使用窗口函数:

 WITH max_pop as (
  SELECT DISTINCT c.id as county_id,
    first_value(g.the_geom) OVER (PARTITION BY c.name ORDER BY g.population DESC) as the_geom
  FROM counties c
  JOIN geonames g
    ON ST_Intersects(c.the_geom,g.the_geom)
  )
UPDATE counties
SET pop_center_geom=max_pop.the_geom
FROM max_pop
WHERE counties.id=max_pop.county_id;

我们在做什么:

按人口降序排列每个县的城市,然后取第一个的几何形状和它所在县的 id。

然后我们使用我们得到的 id 和几何来更新县表。

与提到的 DISTINCT ON 方法相比,我更喜欢这个方法,因为对我来说,它对正在发生的事情更加明确,并且更少依赖“副作用”(因为没有更好的词)。

于 2014-07-28T17:25:09.550 回答