使用MySQL查找距地址一定距离内的城市

时间:2018-01-17 21:30:38

标签: mysql latitude-longitude coordinate-systems geographic-distance

大家:

我完全陷入了这个问题。我尝试添加条件作为WHERE语句,SELECT语句中的IF函数和加入时的ON语句。这些都不会产生我想要的结果。

我需要什么:纬度为0.5度,特定地点经度为0.5度的城市列表。

我给的是什么:两张桌子 - 一张桌子上有特定位置的列表,另一张桌子上有一张美国人口普查所列的城市列表。

表1包括:

Location Address
City
State
Location Latitude
Location Longitude

示例位置数据:

Street              City        State  Latitude     Longitude
774 Emerson Street  Palo Alto   CA     37.44239044  -122.15956879

表2是美国人口普查数据,包括:

City
State
City Latitude
City Longitude

城市数据示例:

City            State Latitude     Longitude
Palo Alto       CA    37.44188309   -122.14302063
Mountain View   CA    37.38605118   -122.08385468
Sunnyvale       CA    37.36883      -122.0363496

例如,如果我在加利福尼亚州帕洛阿尔托有一个位置,我想要的东西看起来像这样:

Location        City          State
Palo Alto CA    Palo Alto     CA
Palo Alto CA    Mountain View CA
Palo Alto CA    Sunnvyale     CA

我试过了:

SELECT d.`City`
      ,d.`State`
      ,l.`City`
      ,l.`StateAbbreviation`
FROM `LocationDirectoryRevised` AS d
     LEFT JOIN
     `LatLong` AS l
     ON d.`City` = l.`City` AND d.`State` = l.`StateAbbreviation`
WHERE l.`Latitude` BETWEEN (d.`Latitude` + 0.5) AND (d.`Latitude` - 0.5)
      AND
      l.`Longitude` BETWEEN (d.`Longitude` + 0.5) AND (d.`Longitude` - 0.5);

我试过了:

SELECT d.`City`
      ,d.`State`
      ,l.`City`
      ,l.`StateAbbreviation`
FROM `LocationDirectoryRevised` AS d
     LEFT JOIN
     `LatLong` AS l
     ON l.`Latitude` BETWEEN (d.`Latitude` + 0.5) AND (d.`Latitude` - 0.5) &&     
        l.`Longitude` BETWEEN (d.`Longitude` + 0.5) AND (d.`Longitude` - 0.5)

我试过了:

SELECT d.`City`
      ,d.`State`
      ,IF((l.`Latitude` < (d.`Latitude` + 0.5)) && (l.`Latitude` > (d.`Latitude` - 0.5)) &&  (l.`Longitude` < (d.`Longitude` + 0.5)) && (l.`Longitude` > (d.`Longitude` - 0.5)), l.`City`,NULL)
      ,l.`StateAbbreviation`
FROM `LocationDirectoryRevised` AS d
     LEFT JOIN
     `LatLong` AS l
     ON d.`City` = l.`City` AND d.`State` = l.`StateAbbreviation`

但这些并没有产生我想要的结果。我错过了什么?

感谢。

3 个答案:

答案 0 :(得分:0)

试试这个:

'\0'

或者,这也有效:

WHERE d.`City` = 'Seattle' AND d.`State` = 'WA'
AND
l.`Latitude` < (d.`Latitude` + 0.5) 
AND 
l.`Latitude > (d.`Latitude` - 0.5)
AND
l.`Longitude` < (d.`Longitude` + 0.5) 
AND 
`l.Longitude` > (d.`Longitude` - 0.5);

答案 1 :(得分:0)

经过大量的工作,我能够使用子查询来计算主要部分并略微调整我的参数:

SELECT `City`
      ,`StateAbbreviation`
      ,`Latitude`
      ,`Longitude`
FROM `LatLong`
WHERE `Latitude` BETWEEN (SELECT `Latitude` - 0.1
                          FROM `LocationDirectoryRevised`
                          WHERE `ID` = 1)
                      AND (SELECT `Latitude` + 0.1
                          FROM `LocationDirectoryRevised`
                          WHERE `ID` = 1)
      AND
      `Longitude` BETWEEN (SELECT `Longitude` - 0.1
                          FROM `LocationDirectoryRevised`
                          WHERE `ID` = 1)
                      AND (SELECT `Longitude` + 0.1
                          FROM `LocationDirectoryRevised`
                          WHERE `ID` = 1);

现在我必须弄清楚如何将其作为所有660个位置的存储过程。如果需要,这将是一个不同的主题。

感谢。

答案 2 :(得分:0)

你可以用这个:

drop procedure if exists getNearLocations;
create procedure getNearLocations();
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
declare e INT default 0;
SELECT COUNT(*) FROM LocationDirectoryRevised INTO n;
SET i=0;
WHILE i<n DO 
select ID from LocationDirectoryRevised into e;
  SELECT `City`
      ,`StateAbbreviation`
      ,`Latitude`
      ,`Longitude`
FROM `LatLong`
WHERE `Latitude` BETWEEN (SELECT `Latitude` - 0.1
                          FROM `LocationDirectoryRevised`
                          WHERE `ID` = e)
                      AND (SELECT `Latitude` + 0.1
                          FROM `LocationDirectoryRevised`
                          WHERE `ID` = e)
      AND
      `Longitude` BETWEEN (SELECT `Longitude` - 0.1
                          FROM `LocationDirectoryRevised`
                          WHERE `ID` = e)
                      AND (SELECT `Longitude` + 0.1
                          FROM `LocationDirectoryRevised`
                          WHERE `ID` = e);
  SET i = i + 1;
END WHILE;
End

这将遍历660个位置并生成您正在寻找的数据。

然而,这可能是一个昂贵的(慢)查询,因为子查询的数量,但对于660个位置,它应该就足够了。