语法 – Postgis中的ST_Distance和’as’

我写了这个查询并且它有效,虽然它有点慢:

SELECT name,
(ST_Distance( ST_Transform( way,900913 ),ST_Transform( ST_GeomFromText('POINT (-6.2222 53.307)',4326),900913 )))
FROM ga_osm_latlong_polygon 
WHERE 
( (ST_Distance( ST_Transform( way,900913 ),ST_Transform( ST_GeomFromText('POINT (-6.2222 53.307)',4326),900913 )))
<= 1000 ) 
ORDER BY
(ST_Distance( ST_Transform( way,900913 ),ST_Transform( ST_GeomFromText('POINT (-6.2222 53.307)',4326),900913 ))),
name

我正试图以更优雅的方式重写它,使用’as’:

SELECT name,
(ST_Distance( ST_Transform( way,900913 ),ST_Transform( ST_GeomFromText('POINT (-6.2222 53.307)',4326),900913 ))) AS d
FROM ga_osm_latlong_polygon 
WHERE ( d <= 1000 ) 
ORDER BY d, name

不幸的是,我得到:
错误:列“d”不存在

关于我在这里遇到什么问题的任何想法?

谢谢!

最佳答案 你好Mulone

关于你的别名问题,路德是对的.

关于查询缓慢有两个原因.

首先,你正在改变每一点,这需要时间

其次,可能更重要的是,你应该将ST_Dwithin与空间索引一起使用,而不是在where子句中使用distance.

ST_Dwithin使用空间索引来排序大量计算.

但是,将数据投射到这些计算中会给出非常不准确的答案.为什么不使用地理功能.

尝试:

SELECT d, name
(
  SELECT ST_Distance(a.way,b.geom) as d, a.name from 
      (SELECT way::geography, name from ga_osm_latlong_polygon) a, 
      (SELECT 'POINT(-6.2222 53.307)'::geography as geom) b 
  where ST_DWithin(a.way, b.geom, 1000)
) c
order by d, name;

但我想我会更简单地写它:

  SELECT ST_Distance(a.way,b.geom) as d, a.name from 
      (SELECT way::geography, name from ga_osm_latlong_polygon) a, 
      (SELECT 'POINT(-6.2222 53.307)'::geography as geom) b 
  where ST_DWithin(a.way, b.geom, 1000)
order by ST_Distance(a.way,b.geom), name;

但第一个版本可能更快,因为避免ST_Distance运行两次.

但是要使这个工作得当好,你需要空间索引
现在,当我写它时,我意识到对地理的投射可能是指数的一个显示.如果是这样,我建议您改为创建一个地理专栏,并在其上建立一个合适的索引.工作指数在这里有所不同,如夜晚和白天.

更新:
或者您可以直接使用地理类型创建索引.我没试过,但可能值得尝试:像这样:

Create index idx_polygon_geog
on ga_osm_latlong_polygon
using gist(way::geography);

HTH

尼克拉斯

点赞