0Pricing
SQL Academy · Lección

Distancia y vecinos más cercanos

Encuentre lo que está cerca.

Distancia y vecinos más cercanos es una lección gratuita de SQL Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de SQL Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de SQL Academy incluye 4 lecciones en total.

¿Qué es la distancia espacial?

En las bases de datos geoespaciales, la distancia es la separación medida entre dos ubicaciones geográficas. PostGIS proporciona funciones potentes para calcular distancias entre puntos, líneas, polígonos y otros tipos de geometría.

Comprender las consultas de distancia permite responder preguntas como: ¿Cuál es el restaurante más cercano? o ¿Qué clientes están a menos de 5 km de nuestro almacén?

La función ST_Distance

ST_Distance(geom_a, geom_b) devuelve la distancia mínima entre dos objetos de geometría. De forma predeterminada, al utilizar tipos geometry simples, el resultado se expresa en las mismas unidades que el sistema de referencia de coordenadas (normalmente grados para EPSG:4326).

Para obtener resultados útiles en metros, debe utilizar tipos geography o reproyectar los datos.

SELECT ST_Distance(
  ST_MakePoint(28.9784, 41.0082)::geography,
  ST_MakePoint(29.0100, 41.0200)::geography
) AS distance_meters;

Configurar una tabla de ejemplo

Creemos una tabla sencilla de lugares con coordenadas geográficas. Utilizaremos el tipo geography para que todos los cálculos de distancia devuelvan automáticamente metros, sin necesidad de realizar una proyección manual.

Esta tabla contendrá cafeterías de una ciudad, cada una con un nombre y una ubicación almacenada como un punto.

CREATE TABLE cafes (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL,
  location GEOGRAPHY(Point, 4326)
);

INSERT INTO cafes (name, location) VALUES
  ('Cafe Alpha',   ST_MakePoint(28.9784, 41.0082)::geography),
  ('Cafe Beta',    ST_MakePoint(28.9900, 41.0150)::geography),
  ('Cafe Gamma',   ST_MakePoint(29.0100, 41.0200)::geography),
  ('Cafe Delta',   ST_MakePoint(28.9650, 40.9980)::geography),
  ('Cafe Epsilon', ST_MakePoint(29.0250, 41.0350)::geography);

Calcular la distancia desde un punto fijo

Una vez que disponga de datos de ubicación, puede calcular la distancia desde cada fila hasta un punto de referencia. Aquí calculamos la distancia desde cada cafetería hasta un usuario situado en las coordenadas (28.9800, 41.0100).

El resultado se expresa en metros porque utilizamos el tipo geography.

SELECT
  name,
  ROUND(
    ST_Distance(
      location,
      ST_MakePoint(28.9800, 41.0100)::geography
    )::NUMERIC
  ) AS distance_m
FROM cafes
ORDER BY distance_m;

Encontrar el vecino más cercano

Para encontrar la única ubicación más cercana a un punto determinado, ordene por distancia y devuelva una sola fila con LIMIT 1. Este es el patrón clásico de consulta del vecino más cercano.

Este patrón es extremadamente común en aplicaciones que tienen en cuenta la ubicación: para encontrar la tienda, el médico o la parada de transporte más cercanos.

SELECT
  name,
  ROUND(
    ST_Distance(
      location,
      ST_MakePoint(28.9800, 41.0100)::geography
    )::NUMERIC
  ) AS distance_m
FROM cafes
ORDER BY location <-> ST_MakePoint(28.9800, 41.0100)::geography
LIMIT 1;

El operador <-> para el vecino más cercano

PostGIS proporciona el operador <-> (KNN — K Nearest Neighbors), que tiene en cuenta los índices. A diferencia de ST_Distance en una cláusula ORDER BY, <-> puede utilizar un índice espacial GiST para evitar recorrer todas las filas.

Utilice siempre <-> en ORDER BY cuando necesite encontrar vecinos cercanos de forma eficiente. Cree un índice como este para admitirlo:

CREATE INDEX ON cafes USING GIST (location);

SELECT
  name,
  ROUND(
    ST_Distance(
      location,
      ST_MakePoint(28.9800, 41.0100)::geography
    )::NUMERIC
  ) AS distance_m
FROM cafes
ORDER BY location <-> ST_MakePoint(28.9800, 41.0100)::geography
LIMIT 5;

Filtrar por distancia (ST_DWithin)

ST_DWithin(geom_a, geom_b, distance) devuelve TRUE cuando dos geometrías se encuentran dentro de una distancia especificada entre sí. Para los tipos geography, la distancia se expresa en metros.

Esto es más eficiente que ST_Distance(...) < radius en una cláusula WHERE porque ST_DWithin tiene en cuenta los índices y deja de buscar en cuanto se cumple la condición.

SELECT
  name,
  ROUND(
    ST_Distance(
      location,
      ST_MakePoint(28.9800, 41.0100)::geography
    )::NUMERIC
  ) AS distance_m
FROM cafes
WHERE ST_DWithin(
  location,
  ST_MakePoint(28.9800, 41.0100)::geography,
  2000
)
ORDER BY distance_m;

Los N más cercanos con un límite de radio

Un patrón habitual en producción combina ST_DWithin como filtro previo con la ordenación mediante <->. La comprobación de ST_DWithin utiliza el índice espacial para descartar rápidamente las filas lejanas y, a continuación, los candidatos restantes se ordenan por distancia exacta.

Esto permite obtener de forma muy eficiente las N ubicaciones más cercanas dentro de un radio máximo.

SELECT
  name,
  ROUND(
    ST_Distance(
      location,
      ST_MakePoint(28.9800, 41.0100)::geography
    )::NUMERIC
  ) AS distance_m
FROM cafes
WHERE ST_DWithin(
  location,
  ST_MakePoint(28.9800, 41.0100)::geography,
  5000
)
ORDER BY location <-> ST_MakePoint(28.9800, 41.0100)::geography
LIMIT 3;

Distancia entre dos tablas (distancia cruzada)

Puede calcular distancias entre filas de dos tablas diferentes mediante un JOIN combinado con ST_Distance. Esto resulta útil para realizar asociaciones, por ejemplo, entre cada cliente y su almacén más cercano o entre cada incidente y el hospital más cercano.

A continuación, buscamos la cafetería más cercana para cada usuario de una tabla users mediante una combinación lateral, un potente patrón de PostgreSQL para las subconsultas por fila.

SELECT
  u.username,
  c.name AS nearest_cafe,
  ROUND(ST_Distance(u.location, c.location)::NUMERIC) AS distance_m
FROM (
  VALUES
    ('alice', ST_MakePoint(28.9810, 41.0095)::geography),
    ('bob',   ST_MakePoint(29.0200, 41.0300)::geography)
) AS u(username, location)
CROSS JOIN LATERAL (
  SELECT name, location
  FROM cafes
  ORDER BY location <-> u.location
  LIMIT 1
) c;

Dar formato al resultado de distancia

Las distancias sin procesar en metros pueden ser difíciles de leer. Puede darles formato en kilómetros o añadir etiquetas fáciles de interpretar mediante expresiones CASE y formato de cadenas. Esta consulta muestra la distancia en metros para distancias cortas y en kilómetros para las más largas.

SELECT
  name,
  CASE
    WHEN ST_Distance(location, ST_MakePoint(28.9800, 41.0100)::geography) < 1000
    THEN ROUND(ST_Distance(location, ST_MakePoint(28.9800, 41.0100)::geography)::NUMERIC)
         || ' m'
    ELSE ROUND((ST_Distance(location, ST_MakePoint(28.9800, 41.0100)::geography) / 1000.0)::NUMERIC, 2)
         || ' km'
  END AS formatted_distance
FROM cafes
ORDER BY location <-> ST_MakePoint(28.9800, 41.0100)::geography;

Asignar una clasificación por distancia

Las funciones de ventana como RANK() y ROW_NUMBER() combinan perfectamente con las consultas de distancia. Puede asignar una clasificación de proximidad a cada ubicación con respecto a un usuario, lo que resulta útil para crear listas de recomendaciones clasificadas o resultados de búsqueda ordenados por cercanía.

SELECT
  name,
  ROUND(
    ST_Distance(
      location,
      ST_MakePoint(28.9800, 41.0100)::geography
    )::NUMERIC
  ) AS distance_m,
  ROW_NUMBER() OVER (
    ORDER BY location <-> ST_MakePoint(28.9800, 41.0100)::geography
  ) AS proximity_rank
FROM cafes;

Comprobación de conocimientos

Compruebe que comprende las consultas de distancia y las búsquedas del vecino más cercano en PostGIS.

Repaso de la lección

En esta lección aprendió a trabajar con distancias espaciales y consultas del vecino más cercano en PostGIS:

  • ST_Distance calcula la distancia exacta entre dos geometrías; utilice el tipo geography para obtener metros automáticamente.
  • ST_DWithin filtra de forma eficiente las filas que se encuentran dentro de un radio mediante el índice espacial; prefiera esta función a ST_Distance < radius en las cláusulas WHERE.
  • El operador <-> (KNN) en ORDER BY tiene en cuenta los índices y es la forma más rápida de obtener los N vecinos más cercanos.
  • Combine ST_DWithin como filtro previo con la ordenación mediante <-> para realizar las consultas más eficientes de los N elementos más cercanos dentro de un radio.
  • CROSS JOIN LATERAL permite encontrar la coincidencia más cercana de otra tabla fila por fila.
  • Las funciones de ventana, como ROW_NUMBER(), pueden asignar clasificaciones de proximidad a los resultados ordenados por distancia.

Estos patrones constituyen la base de las funcionalidades que tienen en cuenta la ubicación en aplicaciones del mundo real.

Preguntas frecuentes

¿La lección «Distancia y vecinos más cercanos» es gratis?

Sí — el texto completo de «Distancia y vecinos más cercanos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de SQL Academy, actualiza a CoddyKit PRO. El curso de SQL Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Distancia y vecinos más cercanos»?

Encuentre lo que está cerca. Practicas SQL Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar SQL Academy?

No se requiere experiencia previa. SQL Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «Distancia y vecinos más cercanos»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de SQL Academy?

Sí. Cada lección de SQL Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Tipos de datos espaciales
  2. Distancia y vecinos más cercanos
  3. Uniones espaciales y contención
  4. Índices espaciales (GiST)
← Volver a SQL Academy