2017-11-23 12 views
0

나는 이것이 지리 정보보다 더 부차적 인 \ join 질문이라고 생각합니다.2 개의 좌표 테이블과 가장 일치 Haversine 수식을 사용하는 MySQL

본질적으로 나는 두 개의 테이블을 가지고 있습니다. 하나 개의 테이블이

을 구성되어
EVENTS 
ID | LAT | LNG | 

두 번째 표는 다음 쿼리는 주어진 작동

POI 
|POIID | LAT | LNG | 

SELECT 
poiid, 
(
    6371 * 
    acos(cos(radians(-32.8857)) * 
    cos(radians(lat)) * 
    cos(radians(lng) - 
    radians(151.7661)) + 
    sin(radians(-32.8857)) * 
    sin(radians(lat))) 
) AS distance 
FROM POI 
=ORDER BY distance LIMIT 1; 

는 내가 원하는 것은 거의 반복적 인 가장 가까운 POI에게 돌아 가야 좌표 이벤트 테이블의 내용은 본질적으로 나에게

OUTPUT 

    |ID| LAT | LONG | *Closest* POIID | 
의 출력을 제공합니다.

는 내가 선택 쿼리

`Select A.ID, A.LAT, A.LONG (SELECT the Haversine formula with A.LAT and A.LONG) from EVENTS A` 

하지만 MySQL의에서이 작업을 수행하기 위해 시도하거나, 내가 어떤 SQL은 선택의 선택에 여러 반환 값을 할 수 있다고 생각하고, 내가 여기서 프로그래머 문제를 생각한다 선택을 가로 질러 계산 ??

희망적입니다. 어떤 도움을 많이 주시면 감사하겠습니다.

답변

0

공간을 많이 차지하는 모든 거리 목록을 만들기 위해 테이블을 완전히 외부 조인하지 않고이 작업을 수행하는 방법을 알지 못합니다. 그런 다음 각 이벤트에 대한 최소값을 선택하기 위해 자체에 합류합니다. - 계산 집약적입니다. 다음은 작동해야하지만 잘 확장되지 않을 수 있습니다 답장을

WITH distances AS ( SELECT p.poiid, e.id, p.lat AS lat, p.lng AS lng, ( 6371 * acos(cos(radians(p.lat)) * cos(radians(e.lat)) * cos(radians(e.lng) - radians(p.lng)) + sin(radians(p.lat)) * sin(radians(e.lat))) ) AS distance FROM poi p CROSS JOIN events e ) SELECT * FROM distances d1 INNER JOIN (SELECT MIN(distance) AS min_dis, id FROM distances GROUP BY id) d2 ON d1.id = d2.id AND d1.distance = d2.min_dis;

+0

감사합니다, 그것은 작동하지 않습니다,하지만 당신이 언급 한 것처럼이 과정에서 매우 많이 사용 .. 아이러니하게도 캔트 사용 열팽창 계수를 MySQL의에 있지만이 어제 CTE를 소개하는 새로운 버전에 대한 초안을 게시했습니다. – cain2060

+0

유스 케이스에 대해 잘 모르겠습니다 ...하지만 각 이벤트에 대해 가장 가까운 POI를 계산하고 저장 한 다음 업데이트 할 것을 제안합니다. 새 이벤트 또는 POI가 추가 될 때 교차 결합을 수행하는 것보다 오히려 하나의 테이블 또는 다른 하나 (예 : 예를 들어)를 통한 단일 패스 만 포함하고 n^2 많은 작업을 수행해야합니다. – WebDev