PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Erhalten aller Gebäude im Umkreis von 5 Meilen von den angegebenen Koordinaten

Warum speichern Sie x,y in getrennten Spalten? Ich empfehle Ihnen dringend, sie als geometry zu speichern oder geography um unnötigen Casting-Overhead in der Abfragezeit zu vermeiden.

Abgesehen davon können Sie mit ST_DWithin Entfernungen in Meilen berechnen und überprüfen oder ST_Distance :

(Testdaten)

CREATE TABLE building (name text, long numeric, lat numeric);
INSERT INTO building VALUES ('Kirk Michael',-4.5896,54.2835);
INSERT INTO building VALUES ('Baldrine',-4.4077,54.2011);
INSERT INTO building VALUES ('Isle of Man Airport',-4.6283,54.0804);

ST_DWithin

ST_DWithin gibt true zurück, wenn die angegebenen Geometrien innerhalb des angegebenen Abstands voneinander liegen. Die folgende Abfrage sucht nach Geometrien, die sich in einem Radius von 5 Meilen um POINT(-4.6314 54.0887) befinden :

SELECT name,long,lat,
  ST_Distance('POINT(-4.6314 54.0887)'::geography,
              ST_MakePoint(long,lat)) * 0.000621371 AS distance
FROM building
WHERE
  ST_DWithin('POINT(-4.6314 54.0887)'::geography,
              ST_MakePoint(long,lat),8046.72); -- 8046.72 metres = 5 miles;

        name         |  long   |   lat   |     distance      
---------------------+---------+---------+-------------------
 Isle of Man Airport | -4.6283 | 54.0804 | 0.587728347062174
(1 row)

ST_Distance

Die Funktion ST_Distance (mit geography Typparameter) gibt die Entfernung in Metern zurück . Mit dieser Funktion müssen Sie am Ende nur Meter in Meilen umrechnen.

Achtung :Entfernungen in Abfragen mit ST_Distance werden in Echtzeit berechnet und verwenden daher keinen räumlichen Index . Es wird daher nicht empfohlen, diese Funktion im WHERE zu verwenden Klausel! Verwenden Sie es lieber im SELECT Klausel. Trotzdem zeigt das folgende Beispiel, wie es gemacht werden könnte:

SELECT name,long,lat,
  ST_Distance('POINT(-4.6314 54.0887)'::geography,
              ST_MakePoint(long,lat)) * 0.000621371 AS distance
FROM building
WHERE 
  ST_Distance('POINT(-4.6314 54.0887)'::geography,
              ST_MakePoint(long,lat)) * 0.000621371 <= 5;

        name         |  long   |   lat   |     distance      
---------------------+---------+---------+-------------------
 Isle of Man Airport | -4.6283 | 54.0804 | 0.587728347062174
(1 row)
  • Achten Sie auf die Reihenfolge der Parameter mit ST_MakePoint :Es ist Längengrad, Breitengrad.. nicht umgekehrt.

Demo:db<>fiddle

Amazon Athena-Äquivalent (Entfernung in Grad):

SELECT *, ST_DISTANCE(ST_GEOMETRY_FROM_TEXT('POINT(-84.386330 33.753746)'),
      ST_POINT(long,lat)) AS distance
FROM building
WHERE 
  ST_Distance(ST_GEOMETRY_FROM_TEXT('POINT(-84.386330 33.753746)'),
  ST_POINT(long,lat)) <= 5;