Consulta SQL de cercanía

En algunas plataformas o implementaciones se requiere procesar información de lugares con sus ubicaciones, almacenando Latitud y Longitud, por ejemplo tiendas, establecimientos, etc. Pero para su funcionamiento se requiere realizar consultas de cercanía, es decir, de acuerdo a un punto central encontrar otros puntos que están cerca alrededor de un radio determinado en kilómetros. Este tipo de consultas requiere conocimiento de la trigonometría pues requieren intervención del seno y coseno y conversión a radianes de la latitud y longitud para obtener correctamente la distancia en kilómetros. En esta ocasión presento una solución que es una consulta SQL para obtener dicha información. La consulta que se ocupa es la siguiente:
SELECT *,  ( 6371 * acos ( cos ( radians(LATITUDE_CENTER) ) * cos( radians(latitude) ) * cos( radians(longitude) – radians(LONGITUDE_CENTER) ) + sin ( radians(LATITUDE_CENTER) ) * sin( radians(latitude) ) ) ) AS distance FROM TABLE HAVING distance < DISTANCE ORDER BY distance LIMIT 0 , 20
 donde
LATITUDE_CENTER: latitud del punto central
LONGITUDE_CENTER: longitud del punto central
latitude: atributo de la table de tipo DOUBLE que almacena la latitude
longitude: atributo de la table de tipo DOUBLE que almacena la longitud
TABLE: tabla sobre la cual se hará la consulta
DISTANCE: distancia en kilómetros a buscar
Veamos un ejemplo. Tenemos el siguiente contexto donde una persona quiere consultar todos los cajeros automáticos que están en un radio de 2 kilómetros. Tenemos la siguiente tabla en un script SQL que se adjunta al final del post. La estructura de la tabla es la siguiente:
Figura 1. Esquema de la base de la tabla ATM
Figura 2. Datos almacenados en la tabla ATM

Teniendo la anterior table, ejecutamos la pasada consulta con un punto central Latitud: 19.535701 y Longitud: -96.903266, en la tabla atm, la consulta que se generaría es el siguiente:

 

SELECT *, ( 6371 * acos ( cos ( radians(19.535701) ) * cos( radians(latitude) ) * cos( radians(longitude) – radians(-96.903266) ) + sin ( radians(19.535701) ) * sin( radians(latitude) ) ) ) AS distance FROM atm HAVING distance < 2 ORDER BY distance LIMIT 0 , 20

El resultado obtenido es una lista de los cajeros automáticos que estén dentro del radio establecido con un atributo más cuyo nombre es distance y devuelve los kilómetros que hay de distancia entre el punto central y dicho punto.  Dichos resultados se ven como los siguientes:

Figura 3. Resultado de la consulta

Como pueden ver, todos los registros están dentro del rango que establecimos (2 Km), por lo que pueden jugar con los valores para observar los diferentes comportamientos.

Espero les haya ayudado esta publicación

Archivo de la Base de Datos: Descargar

Deja un comentario