sql >> Databasteknik >  >> RDS >> PostgreSQL

Få alla byggnader inom räckvidd av 5 miles från angivna koordinater

Varför lagrar du x,y i separerade kolumner? Jag rekommenderar starkt att du lagrar dem som geometry eller geography för att undvika onödig casting overhead i frågetid.

Som sagt, du kan beräkna och kontrollera avstånd i miles med ST_DWithin eller ST_Distance :

(Testdata)

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 returnerar sant om de givna geometrierna är inom det specificerade avståndet från en annan. Följande fråga söker efter geometrier som är inom 5 miles radie från 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

Funktionen ST_Distance (med geography typparametrar) returnerar avståndet i meter . Allt du behöver göra med den här funktionen är att konvertera meter till miles till slut.

Obs :Avstånd i frågor med ST_Distance beräknas i realtid och använder därför inte det rumsliga indexet . Så det rekommenderas inte att använda den här funktionen i WHERE klausul! Använd den hellre i SELECT klausul. Icke desto mindre visar exemplet nedan hur det skulle kunna göras:

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)
  • Ta hänsyn till parametrarnas ordning med ST_MakePoint :Det är longitud,latitud.. inte tvärtom.

Demo:db<>fiddle

Amazon Athena-ekvivalent (avstånd i grader):

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. skickar in tabellnamnet som plsql-parameter

  2. Oracle partitionerat bord

  3. Använd variabel inställd av psql-metakommando inuti DO-blocket

  4. kopiera databasfil från /tillgångar till /data/datamappen i filutforskaren - Android