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;