2011-03-19 4 views
2

양식에서 우편 번호를받습니다. 그런 다음이 우편 번호를 LNG로 변환 할 수 있습니다. 위 좌표는 테이블에 저장되어 있습니다.가장 가까운 장소를 찾기 위해 SQL 서버를 사용하는 Haversine 공식

SELECT lng, lat from postcodeLngLat WHERE postcode = 'CV1'

난 장소의 선택의 LAT는 LNG를 저장하는 다른 테이블을 갖는다. 내가 뭘하려고 오전

SELECT v.lat, v.lng, v.name, p.lat, p.lng, p.postcode, 'HAVERSINE' AS distance FROM venuepostcodes v, postcodeLngLat p WHERE p.outcode = 'CB6' ORDER BY distance

(이 경우에 CV1)에 우편 번호에서 각 장소의 거리를 표시하는 데이터 그리드를 만드는 것입니다. Haversine 수식은 내가 성취하려는 일을해야한다는 것을 알고 있습니다. 그러나 나는 그것을 내 쿼리에 통합해야하는 곳을 잃어 버렸습니다. 나는 수식이 위의 쿼리에 'HAVERSINE'을 넣은 곳으로 가야한다고 생각합니다.

아이디어가 있으십니까?

편집

SELECT o.outcode AS lead_postcode, v.venue_name, 6371.0E * (2.0E *asin(case when 1.0E < (sqrt(square(sin(((RADIANS(CAST(o.lat AS FLOAT)))-(RADIANS(CAST(v.lat AS FLOAT))))/2.0E)) + (cos(RADIANS(CAST(v.lat AS FLOAT))) * cos(RADIANS(CAST(o.lat AS FLOAT))) * square(sin(((RADIANS(CAST(o.lng AS FLOAT)))-(RADIANS(CAST(v.lng AS FLOAT))))/2.0E))))) then 1.0E else (sqrt(square(sin(((RADIANS(CAST(o.lat AS FLOAT)))-(RADIANS(CAST(v.lat AS FLOAT))))/2.0E)) + (cos(RADIANS(CAST(v.lat AS FLOAT))) * cos(RADIANS(CAST(o.lat AS FLOAT))) * square(sin(((RADIANS(CAST(o.lng AS FLOAT)))-(RADIANS(CAST(v.lng AS FLOAT))))/2.0E))))) end)) AS distance FROM venuepostcodes v, outcodepostcodes o WHERE o.outcode = 'CB6' ORDER BY distance

답변

9

난 당신이 최고의 UDF에 넣어 귀하의 질의에 있음을 이용하여 할 거라고 생각 :

SELECT v.lat, v.lng, v.name, p.lat, p.lng, p.postcode, udf_Haversine(v.lat, v.lng, p.lat, p.lng) AS distance FROM venuepostcodes v, postcodeLngLat p WHERE p.outcode = 'CB6' ORDER BY distance 

create function dbo.udf_Haversine(@lat1 float, @long1 float, @lat2 float, @long2 float) returns float begin 
     declare @dlon float, @dlat float, @rlat1 float, @rlat2 float, @rlong1 float, @rlong2 float, @a float, @c float, @R float, @d float, @DtoR float 

     select @DtoR = 0.017453293 
     select @R = 3937 --3976 

     select 
      @rlat1 = @lat1 * @DtoR, 
      @rlong1 = @long1 * @DtoR, 
      @rlat2 = @lat2 * @DtoR, 
      @rlong2 = @long2 * @DtoR 

     select 
      @dlon = @rlong1 - @rlong2, 
      @dlat = @rlat1 - @rlat2 

     select @a = power(sin(@dlat/2), 2) + cos(@rlat1) * cos(@rlat2) * power(sin(@dlon/2), 2) 
     select @c = 2 * atn2(sqrt(@a), sqrt([email protected])) 
     select @d = @R * @c 

     return @d 
    end 
+0

이것을 .net 파일의 .vb 파일에 삽입 할 수 있습니까? 아니면 다른 곳에서이 기능을 사용해야합니까? - "float"비트는 무엇에 관한 것입니까? – Tom

+0

여기서 쓰는 함수는 SQL Server 사용자 정의 함수입니다. 당신은 VB로 변환 할 수 있지만 계산을 수행하려면 모든 데이터를 "클라이언트"로 가져와야합니다. SQL UDF를 사용하면 가장 가까운 상위 10 개를 선택하고 그 중 10 개를 "클라이언트"에만 전송할 수 있습니다 – BlackICE

+0

@Tom - David은 SQL Server에서 함수를 작성한다고 말합니다. UDF -> 사용자 정의 기능. (http://www.google.com/search?q=SQL+Server+UDF) – dana

3

이 대안으로 가다가는 SQL Server 2008을 사용할 수 있습니다 지리 데이터 유형. 현재 경도/위도를 varchar()로 DB에 저장하는 경우 geograpghy 데이터 유형으로 저장 한 다음 STIntersects()와 같은 함수를 사용하여 거리를 구해야합니다.

관련 문제