oracle近似查找,距离内的Oracle空间搜索

对于mySQL距离搜索,你有很好的参考.

忘记Oracle Spatial的东西.代码太多,复杂性太大,没有足够的增值.

这是一个可以解决问题的查询.这使用法定里程的距离.编辑这修复了mdarwin提到的错误,如果你试图将它用于北极或南极的位置,则以划分检查为代价.

SELECT id, city, LATITUDE, LONGITUDE, distance

FROM

(

SELECT id,

city,

LATITUDE, LONGITUDE,

(3959 * ACOS(COS(RADIANS(LATITUDE))

* COS(RADIANS(mylat))

* COS(RADIANS(LONGITUDE) - RADIANS(mylng))

+ SIN(RADIANS(LATITUDE))

* SIN(RADIANS(mylat))

))

AS distance,

b.mydst

FROM Cities

JOIN (

SELECT :LAT AS mylat,

:LONG AS mylng,

:RADIUS_LIMIT AS mydst

FROM DUAL

)b ON (1 = 1)

WHERE LATITUDE >= mylat -(mydst/69)

AND LATITUDE <= mylat +(mydst/69)

AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))

AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))

)a

WHERE distance <= mydst

ORDER BY distance

如果您以公里为单位工作,请将mydst / 69更改为mydst / 111.045,并将3959更改为6371.4. (1/69将英里转换为度数; 3959是行星半径的值.)

现在,您可能会想要将这个大型查询用作“魔术黑盒子”.不要这样做!这不是很难理解,如果你理解它,你将能够做得更好.这是正在发生的事情.

该子句是使查询快速运行的核心.它会在您的Cities表中搜索您指定的点附近的城市.

WHERE LATITUDE >= mylat -(mydst/69)

AND LATITUDE <= mylat +(mydst/69)

AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))

AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))

要使它工作,你肯定需要一个LATITUDE列的索引. LONGITUDE列上的索引也会有所帮助.它进行近似搜索,寻找在您的点附近的地球表面上的准矩形块内的​​行.它选择了太多的城市,但不是太多.

此子句允许您从结果集中删除额外的城市:

WHERE distance <= mydst

该子句是用于计算每个城市与您的观点之间的大圆距离的半正公式.

(3959 * ACOS(COS(RADIANS(LATITUDE))

* COS(RADIANS(mylat))

* COS(RADIANS(LONGITUDE) - RADIANS(mylng))

+ SIN(RADIANS(LATITUDE))

* SIN(RADIANS(mylat))

此子句允许您输入您的点和半径限制,只需输入一次作为查询的绑定变量.它很有用,因为各种公式多次使用这些变量.

SELECT :LAT AS mylat,

:LONG AS mylng,

:RADIUS_LIMIT AS mydst

FROM DUAL

查询的其余部分只是组织事物,以便您按距离选择和排序.