MySQL查询选择最近的城市

时间:2013-08-18 18:12:10

标签: mysql

我正在尝试对所有行重复以下查询。基本上我试图将最近的城市(基于纬度和经度)映射到纬度和经度。我有一个表格位置,其中包含需要映射的位置,以及一个表格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的大小计数(*)。有任何想法吗?另外,如果我的表p包含超过一百万行,还有更有效的方法吗?感谢。

1 个答案:

答案 0 :(得分:1)

您可以使用以下网址找到最近的城市:

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上的索引。

如果这还不够,那么您可以考虑另一种缩小搜索空间的方法,只查看邻近的州(在美国)或国家。

最后,如果您经常处理此类数据,则可能需要考虑geospatial extensions to MySQL