PostgreSQL复杂查询,以查找两个字段的最接近匹配值

时间:2012-12-14 15:10:37

标签: 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

现在我有一些绘制值的代码,当它这样做时会失去一些准确性。用户可以单击这些点并查询数据库以获取有关该点的更多信息。然而,由于绘图功能失去了一些准确性,我需要在查询中考虑到这一点。

所以我的想法是,我想查询time = 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)

1 个答案:

答案 0 :(得分: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