SQL Academy · Leçon

Distance et plus proches voisins

Trouvez ce qui se trouve à proximité.

Leçon 2 sur 413 étapes

Distance et plus proches voisins est une leçon SQL Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage SQL Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours SQL Academy comprend 4 leçons au total.

Qu'est-ce que la distance spatiale ?

Dans les bases de données géospatiales, la distance est l'écart mesuré entre deux emplacements géographiques. PostGIS fournit de puissantes fonctions pour calculer les distances entre des points, des lignes, des polygones et d'autres types de géométrie.

Comprendre les requêtes de distance vous permet de répondre à des questions comme : Quel est le restaurant le plus proche de moi ? ou Quels clients se trouvent à moins de 5 km de notre entrepôt ?

La fonction ST_Distance

ST_Distance(geom_a, geom_b) renvoie la distance minimale entre deux objets géométriques. Par défaut, avec des types de géométrie ordinaires, le résultat est exprimé dans les mêmes unités que le système de référence des coordonnées, généralement en degrés pour EPSG:4326.

Pour obtenir des résultats significatifs en mètres, vous devez utiliser des types de géographie ou reprojeter vos données.

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

Créer une table d'exemple

Créons une table simple de lieux avec leurs coordonnées géographiques. Nous utiliserons le type géographie afin que tous les calculs de distance renvoient automatiquement des mètres, sans projection manuelle.

Cette table contiendra des cafés d'une ville, chacun avec un nom et un emplacement stocké comme un point.

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);

Calculer la distance depuis un point fixe

Une fois les données d'emplacement disponibles, vous pouvez calculer la distance entre chaque ligne et un point de référence. Ici, nous calculons la distance entre chaque café et un utilisateur situé aux coordonnées (28.9800, 41.0100).

Le résultat est exprimé en mètres parce que nous avons utilisé le type géographique.

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

Trouver le voisin le plus proche

Pour trouver le seul emplacement le plus proche d'un point donné, triez les résultats par distance et ne conservez qu'une ligne avec LIMIT 1. Il s'agit de la requête classique du plus proche voisin.

Ce schéma est extrêmement courant dans les applications tenant compte de l'emplacement : trouver le commerce, le médecin ou l'arrêt de transport le plus proche.

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;

L'opérateur <-> pour le plus proche voisin

PostGIS fournit l'opérateur <-> (KNN — K plus proches voisins), qui sait exploiter un index. Contrairement à ST_Distance dans une clause ORDER BY, <-> peut utiliser un index spatial GiST pour éviter de parcourir chaque ligne.

Dans une clause ORDER BY, préférez toujours <-> lorsque vous devez récupérer efficacement les plus proches voisins. Créez un index comme celui-ci pour le prendre en charge :

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;

Filtrer par distance (ST_DWithin)

ST_DWithin(geom_a, geom_b, distance) renvoie TRUE lorsque deux géométries se trouvent à une distance inférieure ou égale à la distance indiquée l'une de l'autre. Pour les types de géographie, la distance est exprimée en mètres.

Cette approche est plus efficace que ST_Distance(...) < radius dans une clause WHERE, car ST_DWithin sait exploiter l'index et s'arrête dès que la condition est satisfaite.

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;

Les N plus proches avec une limite de rayon

Un schéma courant en production consiste à combiner ST_DWithin comme préfiltre avec un tri effectué à l'aide de <->. La vérification avec ST_DWithin utilise l'index spatial pour écarter rapidement les lignes éloignées, puis les candidates restantes sont triées selon leur distance exacte.

Vous obtenez ainsi très efficacement les N emplacements les plus proches dans un rayon maximal.

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;

Distance entre deux tables (distance croisée)

Vous pouvez calculer les distances entre les lignes de deux tables différentes à l'aide d'une jointure JOIN combinée à ST_Distance. Cela est utile, par exemple, pour associer chaque client à l'entrepôt le plus proche ou chaque incident à l'hôpital le plus proche.

Nous cherchons ci-dessous le café le plus proche pour chaque utilisateur d'une table users à l'aide d'une jointure latérale — un schéma PostgreSQL puissant pour effectuer des sous-requêtes ligne par ligne.

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;

Formater le résultat des distances

Les distances brutes en mètres peuvent être difficiles à lire. Vous pouvez les formater en kilomètres ou ajouter des libellés compréhensibles à l'aide d'expressions CASE et du formatage de chaînes. Voici une requête qui affiche les distances en mètres lorsqu'elles sont courtes et en kilomètres lorsqu'elles sont plus longues.

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;

Attribuer un rang selon la distance

Les fonctions de fenêtrage comme RANK() et ROW_NUMBER() s'associent parfaitement aux requêtes de distance. Vous pouvez attribuer un rang de proximité à chaque emplacement par rapport à un utilisateur, ce qui est utile pour créer des listes de recommandations classées ou des résultats de recherche triés selon la proximité.

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;

Vérification des connaissances

Vérifiez votre compréhension des requêtes de distance et des recherches du plus proche voisin dans PostGIS.

Récapitulatif de la leçon

Dans cette leçon, vous avez appris à travailler avec les distances spatiales et les requêtes du plus proche voisin dans PostGIS :

  • ST_Distance calcule la distance exacte entre deux géométries ; utilisez le type géographie pour obtenir automatiquement des mètres.
  • ST_DWithin filtre efficacement les lignes situées dans un rayon donné à l'aide de l'index spatial ; préférez-le à ST_Distance < radius dans les clauses WHERE.
  • L'opérateur <-> (KNN) dans ORDER BY sait exploiter l'index et constitue la méthode la plus rapide pour récupérer les N plus proches voisins.
  • Combinez ST_DWithin comme préfiltre avec le tri effectué à l'aide de <-> pour obtenir les requêtes des N plus proches dans un rayon les plus efficaces.
  • CROSS JOIN LATERAL vous permet de trouver la correspondance la plus proche dans une autre table, ligne par ligne.
  • Les fonctions de fenêtrage comme ROW_NUMBER() peuvent attribuer des rangs de proximité à vos résultats triés par distance.

Ces schémas constituent le socle des fonctionnalités tenant compte de l'emplacement dans les applications du monde réel.

Gratuit pour commencer

Apprends SQL avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
46
Leçons
183

Questions Fréquemment Posées

La leçon « Distance et plus proches voisins » est-elle gratuite ?

Oui — le texte complet de « Distance et plus proches voisins » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours SQL Academy, passe à CoddyKit PRO. Le cours SQL Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Distance et plus proches voisins » ?

Trouvez ce qui se trouve à proximité. Tu pratiques SQL Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer SQL Academy ?

Aucune expérience préalable n'est requise. SQL Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Distance et plus proches voisins » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon SQL Academy ?

Oui. Chaque leçon SQL Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Types de données spatiales
  2. Distance et plus proches voisins
  3. Jointures spatiales et inclusion
  4. Index spatiaux (GiST)
← Retour à SQL Academy