在子查询中使用ST_DWithin(PostGIS)

时间:2012-08-24 08:49:50

标签: subquery postgis

我有一个带点的几何表。所有积分都有唯一的ID。现在我想进行一个查询,我选择一个点(ID为34567)并在此点周围进行5 km的缓冲区分析。我的目标是选择距选定点5公里以外的所有点。所有数据都存储在一个表中。

我尝试了以下内容,

SELECT D.id,D.geometry,S.id,S.geometry 从点AS D,指向AS S. ST_DWithin(D.geometry,S.geometry,5000)和D.id不喜欢'34567'

但是查询会永远运行。

我做错了什么?

所有答案都赞赏

2 个答案:

答案 0 :(得分:2)

最初编写的查询是回答这个问题的一种非常低效的方式,因为它基本上涉及空间自连接,而事实上,OP只想知道距离单点超过5千米的点。 ID = 34567。如果您想要找到距离所有其他点超过5千米的所有点,则会使用自连接,这实际上是0(n ^ 2)运算。

原始查询的解释将显示一个嵌套循环,其中包含两个完整序列扫描(即A点和B点)以及ST_DWithin的空间连接。

查询可以更好地编写为

SELECT count(S.id) FROM points AS S WHERE not ST_Dwithin(S.geometry, 
(select geometry from points where id=34567), 5000);

假设id上有索引,几何上有空间索引。

答案 1 :(得分:0)

感谢JohnBarça。我是新手,但PostGIS手册中的所有示例都包含 geom 功能作为文本,这在正常生活中不太实用。 问题是结果也将返回作为参考的点(34567)。因此,将距离设置为0,返回原始点或count = 1。 我想最快的解决方案是做EXCEPT

SELECT S.id, S.geometry FROM points AS S WHERE not ST_Dwithin(S.geometry, 
(select geometry from points where id=34567), 5000)
EXCEPT
SELECT S.id from POINTS where id=34567

但是你必须把id两次,这对我来说效率也不高。