PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Zdobycie wszystkich budynków w zasięgu 5 mil od określonych współrzędnych

Dlaczego przechowujesz x,y w oddzielnych kolumnach? Zdecydowanie sugeruję, aby zapisać je jako geometry lub geography aby uniknąć niepotrzebnego narzutu w czasie zapytania.

Biorąc to pod uwagę, możesz obliczyć i sprawdzić odległości w milach za pomocą ST_DWithin lub ST_Distance :

(Dane testowe)

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_DZin

ST_DWithin zwraca wartość true, jeśli dane geometrie znajdują się w określonej odległości od innej. Poniższe zapytanie wyszukuje geometrie znajdujące się w promieniu 5 mil od POINT(-4.6314 54.0887) :

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

Funkcja ST_Distance (z geography parametry typu) zwróci odległość w metrach . Korzystając z tej funkcji, wszystko, co musisz zrobić, to na końcu przekonwertować metry na mile.

Uwaga :Odległości w zapytaniach przy użyciu ST_Distance są obliczane w czasie rzeczywistym i dlatego nie używaj indeksu przestrzennego . Dlatego nie zaleca się używania tej funkcji w WHERE klauzula! Użyj go raczej w SELECT klauzula. Niemniej jednak poniższy przykład pokazuje, jak można to zrobić:

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)
  • Uważaj na kolejność parametrów za pomocą ST_MakePoint :to długość geograficzna, szerokość geograficzna.. nie na odwrót.

Demo:db<>fiddle

Odpowiednik Amazon Athena (odległość w stopniach):

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;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Uzyskaj identyfikator ostatniej wkładki po przygotowanej wkładce z PDO

  2. Zwróć wartości kolumn sprzed UPDATE, używając tylko SQL

  3. Dziwne zachowanie w Postgresql

  4. Jak uzyskać różnicę dni/miesięcy/lat (datediff) między dwiema datami?

  5. Niezbędne monitorowanie PostgreSQL — część 1