Se si vuole evitare un'estensione GIS, ho adattato le funzioni da this post a Postgres SQL:
create or replace function change_in_lat(miles numeric)
returns double precision as $$
with v as (select
3960.0 as earth_radius,
180/pi() as radians_to_degrees
) select (miles/earth_radius) * radians_to_degrees from v;
$$ language sql
returns null on null input;
create or replace function change_in_long(lat numeric, miles numeric)
returns double precision as $$
with v as (select
3960.0 as earth_radius,
pi()/180 as degrees_to_radians,
180/pi() as radians_to_degrees
) select (
miles/(earth_radius * cos(lat * degrees_to_radians))
) * radians_to_degrees from v;
$$ language sql
returns null on null input;
utilizzando quelli che si possono fare alcune circostanti quadrati query:
--find all "a"s within 25 miles of any "b"
select * from a join b on (
a.gpslat between
b.gpslat - change_in_lat(25) and b.gpslat + change_in_lat(25)
and a.gpslong between
b.gpslong - change_in_long(b.gpslat::numeric, 25)
and b.gpslong + change_in_long(b.gpslat::numeric, 25)
);
se si usato frequentemente abbastanza sono sicuro che trasformare le dichiarazioni tra una singola funzione sarebbe facile. Con questo però non ho mai fatto nessuna domanda "entro raggio".
Per qualcosa di più complicato, probabilmente vorrai un'estensione GIS come hanno detto altre risposte. PostGIS è buono, ma ho trovato che molte delle funzioni specifiche di gis possono essere difficili da ottenere e, a meno che non si utilizzino indici bounding-box, le query spaziali potrebbero richiedere un giorno se il set di dati è sufficientemente grande. Ma il compromesso della complessità è sicuramente valsa la pena per tutte le cose fantasiose, come l'output dei dati in formato geojson, ecc.