Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何使用Postgres扩展在半径范围内搜索?_Sql_Postgresql - Fatal编程技术网

Sql 如何使用Postgres扩展在半径范围内搜索?

Sql 如何使用Postgres扩展在半径范围内搜索?,sql,postgresql,Sql,Postgresql,求地球表面的距离意味着使用大圆距离,用哈弗森公式计算,也被称为球面余弦定律公式 问题是:给定一张带有纬度和经度的位置表,其中哪些位置距离给定位置最近 我有以下疑问: SELECT z.id, z.latitude, z.longitude, p.radius, p.distance_unit * DEGREES(ACOS(COS(RADIANS(p.latpoint))

求地球表面的距离意味着使用大圆距离,用哈弗森公式计算,也被称为球面余弦定律公式

问题是:给定一张带有纬度和经度的位置表,其中哪些位置距离给定位置最近

我有以下疑问:

 SELECT z.id,
        z.latitude, z.longitude,
        p.radius,
        p.distance_unit
                    * DEGREES(ACOS(COS(RADIANS(p.latpoint))
                    * COS(RADIANS(z.latitude))
                    * COS(RADIANS(p.longpoint - z.longitude))
                    + SIN(RADIANS(p.latpoint))
                    * SIN(RADIANS(z.latitude)))) AS distance
 FROM doorbots as z
 JOIN (   /* these are the query parameters */
    SELECT 34.0480698 AS latpoint, -118.3589196 AS longpoint,
           2 AS radius,  111.045 AS distance_unit
      ) AS p ON 1=1
 WHERE z.latitude between ... and 
       z.longitude between ...
如何使用扩展来更改查询中的复杂公式

这是否等同于改变

SELECT z.id,
       z.latitude, z.longitude,
       p.radius,
       round(earth_distance(ll_to_earth(p.latpoint, p.longpoint), ll_to_earth(z.latitude, z.longitude))::NUMERIC,0) AS distance
 FROM doorbots as z
 JOIN (   /* these are the query parameters */
    SELECT 34.0480698 AS latpoint, -118.3589196 AS longpoint,
           2 AS radius,  111.045 AS distance_unit
      ) AS p ON 1=1
 WHERE z.latitude between ... and 
       z.longitude between ...

通过以下查询,您可以充分利用earthdistance:

位置足够近,即在1000000.0米范围内-621.371192英里至34.0480698,-118.3589196:

使用索引:足够近的位置,即在1000000.0米-621.371192英里到34.0480698,-118.3589196之间:

使用索引:最接近34.0480698,-118.3589196的前5个位置:


通过以下查询,您可以充分利用earthdistance:

位置足够近,即在1000000.0米范围内-621.371192英里至34.0480698,-118.3589196:

使用索引:足够近的位置,即在1000000.0米-621.371192英里到34.0480698,-118.3589196之间:

使用索引:最接近34.0480698,-118.3589196的前5个位置:


地球到地球的距离地球到地球的纬度,经度,地球到地球的距离$1,$2<$3或点z.经度,纬度点$2,$1<$3-关于地球距离的文档对我来说似乎很明显。你到底不明白什么也许你想加入一些索引?对于你的更新:是的,这似乎是一个相当的变化,但是z.latitude之间。。。和z之间的经度。。。不在半径范围内搜索;相反,在一个矩形中,它实际上也不是一个矩形:它是一个球形表面上的一个矩形区域。地球到地球的距离。纬度,经度,地球到地球的距离$1,$2<$3或点z.经度,z.纬度点$2,$1<$3。关于地球距离的文档对我来说似乎很明显。你到底不明白什么也许你想加入一些索引?对于你的更新:是的,这似乎是一个相当的变化,但是z.latitude之间。。。和z之间的经度。。。不在半径范围内搜索;实际上,在矩形中,它也不是矩形:它是球形表面上的矩形区域。
select *
from   doorbots z
where  earth_distance(ll_to_earth(z.latitude, z.longitude), ll_to_earth(34.0480698, -118.3589196)) < 1000000.0; -- in meters

select *
from   doorbots z
where  point(z.longitude, z.latitude) <@> point(-118.3589196, 34.0480698) < 621.371192; -- in miles
select   *
from     doorbots z
order by earth_distance(ll_to_earth(z.latitude, z.longitude), ll_to_earth(34.0480698, -118.3589196))
limit    5;

select   *
from     doorbots z
order by point(z.longitude, z.latitude) <@> point(-118.3589196, 34.0480698)
limit    5;
create index idx_doorbots_latlong
  on doorbots using gist (earth_box(ll_to_earth(latitude, longitude), 0));
with p as (
  select 34.0480698   as latitude,
         -118.3589196 as longitude,
         1000000.0    as max_distance_in_meters
)
select z.*
from   p, doorbots z
where  earth_box(ll_to_earth(z.latitude, z.longitude), 0) <@ earth_box(ll_to_earth(p.latitude, p.longitude), p.max_distance_in_meters)
and    earth_distance(ll_to_earth(z.latitude, z.longitude), ll_to_earth(p.latitude, p.longitude)) < p.max_distance_in_meters;
select   z.*
from     doorbots z
order by earth_box(ll_to_earth(z.latitude, z.longitude), 0) <-> earth_box(ll_to_earth(34.0480698, -118.3589196), 0)
limit    5;