2014-09-22 2 views
0

두 테이블이 있습니다 프로젝트위치는입니다. 프로젝트는 locations.project_id reference를 사용하여 여러 위치를 가질 수 있습니다. 또한 위치에는 위치, 위치는 및 위치는 입니다. 길이는입니다.조인 된 테이블에서 최소 지리적 거리를 얻으십시오

저는 현재 모든 프로젝트와 고정 소수점까지의 최소 거리를 쿼리하는 효율적인 방법을 찾고 있습니다. 테이블에 각각 2 개의 프로젝트가 있고, 2 개의 프로젝트를 얻고 싶습니다. 고정 된 위치에 가장 가까운 한 위치까지의 거리를 얻고 싶습니다.

I 편의를위한 .geography 기능을 만들었습니다

CREATE FUNCTION geography(locations) RETURNS GEOGRAPHY AS $$ 
    SELECT ST_GeographyFromText(
    'SRID=4326;POINT(' || $1.latitude || ' ' || $1.longitude || ')' 
) 
$$ LANGUAGE SQL 

지금 다음 예제에서 사용하는 "취리히 (47.36865, 8.539183)"고정 지점으로 :

SELECT 
    ST_Distance(locations.geography, ST_GeographyFromText('SRID=4326;POINT(47.36865 8.539183)')) AS distance 
    FROM "projects" 
    INNER JOIN "locations" ON "locations"."project_id" = "projects"."id" 

쿼리 작업, 그러나 가장 가까운 생성 날짜가 아니라 가장 오래된 생성 날짜를 가진 위치까지의 거리를 반환합니다. 어떤 태도로이 문제를 해결할 수 있을까요?

UPDATE

내 질문은 모두 잘못된 것입니다. 내가 성취하고자하는 것은 CTE에서 아주 쉽습니다. 그러나 그것은 또 다른 이야기입니다. 소음에 대해 사과드립니다.

+0

나는 귀하의 질문에 완전히 따르지 않습니다. 테이블과 쿼리에 작성 날짜가 어디에 맞습니까? 당신은 두 개의 동일한 위치를 가지고 있다고 말하면서 창조 날짜를 위해, 당신은 가장 최신의 것만 원하십니까? –

+0

@ JohnBarça 프로젝트에 둘 이상의 위치가있는 경우 INNER JOIN은 데이터베이스에서 처음으로 오는 것 (일반적으로 가장 오래된 위치)에서만 작동하고 거리를 계산합니다. 처음에 고정 소수점에서 멀리 떨어진 위치를 만들고 나서 고정 소수점에서 많이 닫힌 위치를 만들면 위의 쿼리는 먼저 추가 된 이후 큰 거리를 반환합니다. 삽입 될 때마다 가장 짧은 거리가 필요합니다. – svoop

+0

st_distance (...)로 주문 desc? –

답변

1

PostGIS는 위도, 경도 (X, Y로 생각)의 축 순서를 사용합니다. 스위스가 아닌 소말리아에서 현재 찾고있는 것처럼 거리가 예상 한 것과 다를 수 있습니다.

또한 접근 방식은 geography 유형을 지속적으로 생성하고 공간 인덱스가 없으므로 실제로 비효율적입니다. , 공간 형태로 데이터를 이동 및 중복 열을 제거하는 것이 좋습니다 예 :

ALTER TABLE locations ADD COLUMN geog geography(Point,4326); 
UPDATE locations SET 
    geog=ST_SetSRID(ST_MakePoint(longitude, latitude), 4326)::geography; 
CREATE INDEX locations_geog_idx ON locations USING gist (geog); 
ALTER TABLE locations DROP COLUMN latitude; 
ALTER TABLE locations DROP COLUMN longitude; 

당신은 항상 액세스하고 47 ° 22'7.140 "N 같은 문자열에 대한 경도 ST_X, 또는 ST_AsText 또는 ST_AsLatLonText(geog::geometry)를 사용하여 데이터를 볼 수 있습니다 8 ° 32'21.059 "E. 귀하의 질의 :

SELECT 
    ST_Distance(locations.geog, 
       ST_SetSRID(ST_MakePoint(8.539183, 47.36865), 4326)::geography)')) 
    AS distance 
FROM "projects" 
INNER JOIN "locations" ON "locations"."project_id" = "projects"."id"; 
+0

당신은 긴/위도 주문에 대해 옳았습니다.이 사례에 대한 실제 사례를 슬림화했을 때 이런 일이 발생했습니다. 그것에 대한 색인도 있습니다. 나는 당신의 정교하고 정확한 대답에 감사 드리기 위해 어쨌든 당신의 대답을 올리고 있습니다. 제 질문은 잘못되었습니다. – svoop

관련 문제