2012-12-14 53 views
0

您好我有以下結構的數據庫:PostgreSQL的複雜查詢找到最匹配的兩個字段的值

表1:

time(type timestamp)  longitude(type string)  latitude(type string) 
2:00      -110.4365      38.7463 
2:00      -110.2743      38.7983 
2:00      -102.4434      36.9438 
3:00      -112.3254      39.2222 
etc       etc       etc 

現在我有一些代碼,繪製值,並且當它因此失去了一些準確性。用戶可以單擊這些點並查詢數據庫以獲取關於該點的更多信息。然而,由於繪圖功能失去了一些準確性,我需要在查詢中解釋這一點。

這樣的想法是,我想查詢時間= x和也(緯度=最接近值y和經度=最接近的值到z)。你看最近的值取決於經度和緯度而這正是我越來越困惑,如何進行。

可以說,我一直在尋找:

Time = 2:00 
Longitude = -110.3421 
Latitude = 38.7587 

現在,如果我做一個查詢:

Time = 2:00 and Longitude = closest to -110.3421 

那麼結果將是第2行。

但是,如果我做的:

Time = 2:00 and Latitude = closest to 38.7587 

然後結果將第1行中

如果我做一個查詢:

Time = 2:00 and Longitude = closest to -110.3421 and Latitude = closest to 38.7587 

那麼結果將是第1行。這是我需要查詢的類型......

我找到了以下職位上最接近值的查詢有用的一個領域:

https://stackoverflow.com/a/6103352/1800665

謝謝, 詹姆斯

編輯:我有以下幾點:

(SELECT * FROM (
(SELECT * FROM Table1 WHERE cast(latitude as double precision) >= '38.7587' AND healthtime = '2:00' AND cast(longitude as double precision) >= '-110.3421') 
UNION ALL 
(SELECT * FROM Table1 WHERE cast(latitude as double precision) < '38.7587' AND healthtime = '2:00' AND cast(longitude as double precision) < '-110.3421') 
) as nearest ORDER BY (abs('38.7587'-cast(latitude as double precision)) + abs('-110.3421'-cast(longitude as double precision))) LIMIT 1) 
+0

聽起來像是你想http://postgis.refractions.net/ –

+0

謝謝,但最好我想不必安裝附加軟件。緯度和經度字段實際上是字符串類型,而不是地理數據類型。 –

+0

另請注意,「(最接近X,最接近Y)」不同於「最接近(X,Y)」。 –

回答

1

你可以嘗試這樣的事情:

SELECT * 
FROM table1 
WHERE healthtime = '2:00' 
ORDER BY ((longitude::double precision - (-110.3421))^2 + 
      (latitude::double precision - (38.7587 ))^2) 
LIMIT 1 

它將返回您以最小的 「距離」 的點:((lon-lon1)^2 + (lat-lat1)^2 -> min)。

SQLFiddle有例子。

UPD測試查詢:

SELECT *, ((longitude::double precision - (-110.3421))^2 + 
      (latitude::double precision - (38.7587 ))^2) as distance, 
      (abs(longitude::double precision - (-110.3421)) + 
      abs(latitude::double precision - (38.7587 ))) as distance2 
FROM table1 
WHERE time = '2:00' 
ORDER BY ((longitude::double precision - (-110.3421))^2 + 
      (latitude::double precision - (38.7587 ))^2) 

LIMIT 2 

2個給出最好的結果:

| TIME | LONGITUDE | LATITUDE | DISTANCE | DISTANCE2 | 
-------------------------------------------------------- 
| 2:00 | -110.2743 | 38.7983 | 0.006165 | 0.1074 | 
| 2:00 | -110.4365 | 38.7463 | 0.00906512 | 0.1068 | 

DISTANCE = (lon-lon1)^2 + (lat-lat1)^2(我的變體)。

DISTANCE2 = abs(lon-lon1) + abs(lat-lat1)(您的變體)。

您的變體給出了不同的「最接近」。您可以使用任何「距離」計算的變體,但我更喜歡「古典」方式 - root((lon-lon1)^2 + (lat-lat1)^2)

SQLFiddle

+0

謝謝,但我想知道爲什麼你會得到與我不同的答案?當我手動解決問題時,我得到了第一行作爲最接近的匹配... –

+0

@JamesElder查看我的更新。 –