2010-07-16 72 views
1

我有一個SQL數據庫,用於存儲iPhone應用程序的經度和緯度。我需要查詢從給定位置開始到最遠位置的所有記錄。在SQL中查找和排序經度和緯度

例如,我有經度x和緯度y。我希望所有記錄的第一個經度匹配x最接近,其緯度最接近y的記錄。我需要從最近到最遠的鏈條中的所有記錄。位置越遠,經度和緯度的值將大於x和y。

我希望你明白了,我正在等待答案。

回答

0

假設你查詢的起始位置緯度/經度和位置ID ...我使用$ LAT,LON $和$ ID爲佔位符:

select locID, locName, locDesc, lat, lon, locDiff 
from (
    select locID, locName, locDesc, lat, lon, ABS(lat - $LAT) + ABS(lon - $LON) as locDiff 
     from locationTable 
    where locID <> $ID 
) a 
order by locDiff 

希望這有助於...可能不是最優化的方法,但它應該非常接近。

+0

對不起,但你能解釋這個查詢嗎? – Neutralizer 2010-07-18 20:07:59

+0

它的哪一部分讓你感到困惑?內部子查詢會拉出除比較對象之外的所有位置,並從您正在比較的位置中減去緯度和經度值。它使用ABS函數來獲得結果的絕對值(非負值)。外部查詢只是從距離排序的內部查詢中提取數據。看完之後,我會推薦Mark Ba​​nnisters的答案,它使用更準確的定理。 – Fosco 2010-07-18 22:02:06

1

類似Fosco,但使用勾股定理:

select locID, locName, locDesc, lat, lon, locDiff from 
(select locID, locName, locDesc, lat, lon, 
sqrt((lat - $LAT)*(lat - $LAT) + (lon - $LON)*(lon - $LON)) as locDiff 
from locationTable 
where locID <> $ID) a 
order by locDiff 

對於真正大的距離(或位置遠離赤道)您應使用測地線。

2

與經緯度的距離不是一個簡單的計算,而是一個需要球面三角。

acos(cos(lat1)*cos(lon1)*cos(lat2)*cos(lon2) + 
    cos(lat1)*sin(lon1)*cos(lat2)*sin(lon2) + 
    sin(lat1)*sin(lat2)) * R(adius of the earth) 

所以這個查詢

select locID, locName, locDesc, lat, lon, locDiffMeters 
from (select locID, locName, locDesc, lat, lon, 
      acos(cos($lat)*cos($lon)*cos(lat)*cos(lon) + 
        cos($lat)*sin($lon)*cos(lat)*sin(lon) + 
        sin($lat)*sin(lat)) * 6,371,000 -- earths radius in meters 
       as locDiffMeters 
     from locationTable  
    where locID <> $ID  
) a  
order by locDiffMeters  

可能是正確的答案,假設你有一個能夠在數學庫。

+0

你的答案看起來很酷。我不擅長數學,但試圖找出你的問題。 你能告訴我爲什麼你的查詢中除了Lon/Lat之外還有其他字段? – Neutralizer 2010-07-18 20:06:58

+0

我在上面/下面使用了Fosco的基本查詢,只是將不同的計算更改爲使用球體上的實際距離。您需要一個起點(由$ ID,$ LAT和$ LON表示),並且我們假設您的點表具有locID,locName,locDesc,lat和lon。你沒有提供表格定義;如果提供了(提示,提示),我們會使用一個。 – 2010-07-19 13:25:47

0

如果你不需要處理很大的距離(參見Adam的答案),你可以考慮使用PostgreSQL的geometric types和相關的functions

0

如果你使用PostgreSQL,添加PostGIS延伸,並檢查了ST_Distance_Sphere

ST_Distance_Sphere - 返回兩個經度/緯度幾何米之間的最小距離。使用球形地球,半徑6370986米。比ST_Distance_Spheroid更快,但不太準確。 1.5之前的PostGIS版本僅適用於點。

SELECT round(CAST(ST_Distance_Sphere(ST_Centroid(the_geom), ST_GeomFromText('POINT(-118 38)',4326)) As numeric),2) As dist_meter ...