3

我正在尝试对所有行重复以下查询。基本上我正在尝试将最近的城市(基于纬度和经度)映射到纬度和经度的地方。我有一个表 places ,其中包含需要映射的位置,还有一个表 CityTable ,其中包含要匹配的位置。我有以下适用于单行的查询:

SELECT p.placeID, p.State, p.City, p.County, p.name, 
       SQRT(POW((69.1 * (p.lat - z.Latitude)), 2 ) 
       + POW((53 * (p.lng - z.Loungitude)), 2)) AS distance,
       p.lat,p.lng,z.Latitude,z.Loungitude,z.City 
FROM places p,CityTable z 
WHERE p.placeID = 1 
ORDER BY distance ASC 
LIMIT 1;

这适用于单个位置。显然,我需要删除 WHERE 约束才能将其应用于整个表。我遇到的问题是它似乎想要制作一个副本以与表中的每个其他元素进行比较。例如,如果 p 中有 100 行,z 中有 100 行,那么结果表似乎是 10,000 行。我需要表格的大小为 p 的 count(*)。有任何想法吗?此外,如果我的表 p 包含超过一百万行,是否有更有效的方法来做到这一点?谢谢。

4

1 回答 1

2

您可以使用以下方法找到离某个地点最近的城市:

SELECT p.placeID, p.State, p.City, p.County, p.name, 
       (select z.City
        from CityTable z
        order by SQRT(POW((69.1 * (p.lat - z.Latitude)), 2 ) + POW((53 * (p.lng - z.Loungitude)), 2)) 
        limit 1
       ) as City,
       p.lat, p.lng
FROM places p
ORDER BY distance ASC;

(如果您想了解更多城市信息,请重新加入城市表City。)

这并不能解决必须做笛卡尔积的问题。然而,它确实以不同的方式构建它。如果您知道一个城市在任何地方的经度/纬度五度以内,那么您可以使子查询更高效:

       (select z.City
        from CityTable z
        where z.lat >= p.lat + 5 and z.lat <= p.lat - 5 and
              z.long <= p.long + 5 and z.long <= p.lat - 5
        order by SQRT(POW((69.1 * (p.lat - z.Latitude)), 2 ) + POW((53 * (p.lng - z.Loungitude)), 2)) 
        limit 1
       ) as City,
       p.lat, p.lng;

此查询将使用lat. 它甚至可能在lat, long.

如果这还不够,那么您可能会考虑另一种减少搜索空间的方法,即仅查看邻国(在美国)或国家/地区。

最后,如果您经常处理此类数据,您可能需要考虑对 MySQL 的地理空间扩展。

于 2013-08-18T19:02:54.270 回答