PostgreSQL:输入超出范围

时间:2019-05-15 10:06:37

标签: sql postgresql

我正在尝试创建查询以获取2个位置之间的距离。

https://developers.google.com/maps/solutions/store-locator/clothing-store-locator

链接示例:

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;

基于示例链接,我创建了以下查询。

select ( 6371 * acos( cos( radians(3.139003) ) * cos( radians( 3.10726 ) ) * cos( radians( 101.60671 ) - radians(101.68685499999992) ) + sin( radians(3.139003) ) * sin( radians( 101.60671 ) ) ) ) AS distance from requests

位置1:3.19003,101.68685499999992

位置2:3.10726、101.60671

但是,查询总是由于输入超出范围而失败,这似乎是由于acos造成的。

任何人都可以为此提供一些指示吗?

3 个答案:

答案 0 :(得分:1)

是的,这很简单。

最左边的acos函数的参数是

cos( radians(3.139003) )
* cos( radians( 3.10726 ) )
* cos( radians( 101.60671 )
       - radians(101.68685499999992) )
+ sin( radians(3.139003) ) * sin( radians( 101.60671 ) )

其值为1.05066948199501。

但是[-1,1]范围之外的任何内容都不是acos的有效参数。

答案 1 :(得分:1)

最后一个sin应该是sin(radian(lat)),但是您改用了经度。将sin( radians( 101.60671 )替换为sin( radians( 3.10726 )

答案 2 :(得分:1)

我知道这并不能特别回答这个问题,但是这是我为postgres保存的查询,它使用Haversine公式计算了以km为单位的2个点之间的距离。我发现它相当简单和准确。

SELECT asin(
  sqrt(
    sin(radians(latB - latA)/2)^2 +
    sin(radians(lonB - lonA)/2)^2 *
    cos(radians(latA)) *
    cos(radians(latB))
  )
) * (6371 * 2) AS distance;