2013-08-18 173 views
2

我想重复所有行的以下查询。基本上我试图将最接近的城市(基于经度和纬度)映射到经度和纬度的地方。我有一个包含需要映射的地方的表格地方,以及包含要匹配的地方的表格CityTable。我有以下查询适用于单行:MySQL查询选择最近的城市

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包含超过一百万行,是否还有更有效的方法来做到这一点?谢谢。

+0

要查找每个地点的城市,您可以**每个城市与每个城市进行比较。 – Cthulhu

+2

重复?阅读此:http://stackoverflow.com/questions/1006654/fastest-way-to-find-distance-between-two-lat-long-points – iiro

+0

如果我想比较每个城市与每个城市,如何我会把这个投入循环?谢谢。 – user2694306

回答

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