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