Postgres SQL(Amazon Redshift) - 如何计算两个纬度和经度之间的距离?

时间:2014-08-14 19:33:55

标签: sql amazon-web-services amazon-redshift

在Netezza中,我习惯使用INZA包和ST_Distance函数。 Redshift中是否有人知道类似的方式?我用它进行了大量的计算和连接。

4 个答案:

答案 0 :(得分:7)

检查一下!!

------- DISTANCE FUNCTION ---------
CREATE FUNCTION DISTANCE (orig_lat float, orig_long float, dest_lat float, dest_long float)
  RETURNS float
STABLE  
AS $$
  import math
  r = 3963.1676          
  phi_orig = math.radians(orig_lat)
  phi_dest = math.radians(dest_lat)
  delta_lat = math.radians(dest_lat - orig_lat)
  delta_long = math.radians(dest_long - orig_long)
  a = math.sin(delta_lat/2) * math.sin(delta_lat/2) + math.cos(phi_orig) \
      * math.cos(phi_dest) * math.sin(delta_long/2) * math.sin(delta_long/2)
  c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
  d = r * c
  return d
$$ LANGUAGE plpythonu
;

答案 1 :(得分:1)

alexanderlz建议的postgres_fdw模块不能与Redshift一起使用,因为最低要求是Postgres 8.1(只读)。 Redshift目前使用Postgres 8.0.2。您可以使用dblink来获得类似的功能。

答案 2 :(得分:0)

您必须计算外部 redshift,

您可以尝试以下方法:

由于redshift实现了postgres界面,你可以利用postgres FDW的能力,并将它们统一到一个postgres数据源,你可以在一个查询中进行连接。

即。 :postgres的实例(称之为“master”),安装了postgis,通过 fdw 连接到redshift。这样,您就可以对红移数据使用地理定位查询。

答案 3 :(得分:0)

虽然python udf方法没有任何问题,但我们发现python udf比本地sql udf花费的时间更长,消耗的资源也更多(并且我们运行了数十亿条记录)。这就是我们使用的方法,并且肯定不是完美的方法(即,我们将地球半径平均为3961英里,但我们不需要精确使用)。

CREATE OR REPLACE FUNCTION public.f_haversine (
  float, -- $1: latitude_1
  float, -- $2: longitude_1
  float, -- $3: latitude_2
  float  -- $4: longitude_2
)  
  RETURNS FLOAT
  IMMUTABLE
AS $$
  SELECT 2 * 3961 * ASIN(SQRT( POWER((SIN(RADIANS(($3 - $1) / 2))) , 2) + COS(RADIANS($1)) * COS(RADIANS($3)) * POWER((SIN(RADIANS(($4 - $2) / 2))) , 2) ))
$$ LANGUAGE sql;

这只是使用内置的sql数学功能手动计算的Haversine距离。这将返回以英里为单位的距离,如果要以另一度量单位返回距离,则可以将3961替换为您想要的任何单位的地球平均半径(即6371公里,或者6371000代表米等)