2016-06-15 16 views
2

こんにちは私はpostgresql database.Butで緯度と経度で最も近い場所を見つけようとしています。postgresqlの緯度と経度で最も近い場所を見つける

ERROR: column "distance" does not exist 
LINE 1: ...))) AS distance FROM station_location HAVING distance <... 
                  ^
********** Error ********** 

ERROR: column "distance" does not exist 
SQL state: 42703 
Character: 218 

CREATE TABLE station_location 
(
    id bigint NOT NULL DEFAULT nextval('location_id_seq'::regclass), 
    state_name character varying NOT NULL, 
    country_name character varying NOT NULL, 
    locality character varying NOT NULL, 
    created_date timestamp without time zone NOT NULL, 
    is_delete boolean NOT NULL DEFAULT false, 
    lat double precision, 
    lng double precision, 
    CONSTRAINT location_pkey PRIMARY KEY (id) 
) 

SELECT *,(3959 * acos(cos(radians(6.414478)) * cos(radians(lat)) * cos(radians(lng) - radians(12.466646)) + sin(radians(6.414478)) * sin(radians(lat)))) AS distance 
FROM station_location 
HAVING distance < 5 
ORDER BY distance 
LIMIT 20; 
+0

id bigint NOT NULL DEFAULT nextval( 'location_id_seq' :: regclass)を実行すると、 'id bigserial'に書き直してください - 時間を節約できます –

答えて

1
select * from (
SELECT *,(3959 * acos(cos(radians(6.414478)) * cos(radians(lat)) * cos(radians(lng) - radians(12.466646)) + sin(radians(6.414478)) * sin(radians(lat)))) AS distance 
FROM station_location 
) al 
where distance < 5 
ORDER BY distance 
LIMIT 20; 
0

参照this gist、あなたはpointタイプとどのように順行距離を返すようにdistance演算子をオーバーライドするためにDOMAINを宣言する方法を見つけるでしょう。

pointから継承latlongタイプ宣言:

CREATE DOMAIN latlong AS point CHECK (VALUE[0] BETWEEN -90.0 AND 90.0 AND VALUE[1] BETWEEN -180 AND 180); 

キロにおける順行距離(地球半径を有する球面上の距離):

CREATE OR REPLACE FUNCTION orthodromic_distance(latlong, latlong) RETURNS float AS $_$ 
    SELECT acos(
       sin(radians($1[0])) 
      * 
       sin(radians($2[0])) 
      + 
       cos(radians($1[0])) 
      * 
       cos(radians($2[0])) 
      * 
       cos(radians($2[1]) 
      - 
       radians($1[1])) 
      ) * 6370.0; 
$_$ LANGUAGE sql IMMUTABLE; 

この機能を使用して距離演算<->をオーバーライドlatlongsで使用する場合:

CREATE OPERATOR <-> (PROCEDURE = orthodromic_distance 
, LEFTARG = latlong, RIGHTARG = latlong 
); 
01あなたのSQLクエリで今

、最寄りのエンティティを見つけるために:

WITH 
    station_distance AS (
    SELECT 
     id AS station_id, 
     point(lat, long)::latlong <-> point(6.414478, 12.466646)::latlong AS distance 
    FROM station_location 
    WHERE NOT is_deleted 
) 
    SELECT 
    sl.state_name, 
    sl.country_name, 
    sl.locality, 
    point(sl.lat, sl.long)::latlong AS coordinates, 
    sd.distance 
    FROM 
    station_location sl 
    JOIN station_distance sd 
     ON sd.station_id = sl.id 
    ORDER BY 
    distance ASC 
    LIMIT 10 

あなたはおそらくLatLongブログタイプを使用して、同じフィールドに位置latlongを保存したいです。

関連する問題