从邮政编码表(MySql)获取纬度和经度并加入另一个表

Posted

技术标签:

【中文标题】从邮政编码表(MySql)获取纬度和经度并加入另一个表【英文标题】:Getting latitude and longitude from a postcode table (MySql) and joining to another table 【发布时间】:2012-11-21 10:11:26 【问题描述】:

我有一个慈善机构表,其中包含以下字段:慈善机构、邮政编码 和一个包含以下字段的邮政编码表:邮政编码、纬度、lng

我想在网页上发布邮政编码并找到最近的慈善机构

我是一个 mysql 初学者,所以我有点迷茫,但我一直在尝试使用连接和子查询的各种想法,但都不起作用(我要么遇到语法错误,要么'操作数应该包含 1 列'与下面的代码变体)我有

Select charity,postcode,
 ( 
   (Select lat as lat2, lng as lng2
    from postcodes
    where postcode='WN8'
    )

3959 * acos( cos( radians(lat2) ) * cos( radians( lat ) ) * 
cos( radians( lng ) - radians(lng2) ) + 
sin( radians(lat2) ) * sin( radians( lat ) ) ) 
  )
AS distance 
FROM postcodes  
JOIN   Charities on charities.postcode=postcodes.postcode
HAVING distance < 30 ORDER BY distance LIMIT 0 , 30;

我在这里看到了很多例子,其中 lat2 和 lng2 是从发布的值中获得的,而不是从数据库中的表中获得的。

示例中的 p.s 'where postcode='WN8' 仅用于测试

【问题讨论】:

检查一下,它看起来和你需要的很相似blog.loftdigital.com/blog/geolocation-and-sql 【参考方案1】:

不确定上述 SQL 遇到了什么错误。

不过,试试这个小调整,让我们知道您遇到了什么错误

SELECT charity, postcode,
(3959 * acos( cos( radians(CustPostcode.lat) ) * cos( radians( postcodes.lat ) ) * 
cos( radians( postcodes.lng ) - radians(CustPostcode.lng) ) + 
sin( radians(CustPostcode.lat) ) * sin( radians( postcodes.lat ) ) ) 
  ) AS distance 
FROM postcodes  
INNER JOIN Charities ON charities.postcode=postcodes.postcode
CROSS JOIN  (SELECT lat, lng FROM postcodes WHERE postcode='WN8') CustPostcode
HAVING distance < 30 
ORDER BY distance 
LIMIT 0 , 30;

如果您想知道最近的 30 个邮政编码以及与每个慈善机构的距离,那么这样的事情就可以完成(未经测试,请原谅任何拼写错误)。

SELECT charity, Charities.postcode, Postcodes.postcode, PostcodeDistance.distance
FROM Charities
CROSS JOIN Postcodes
INNER JOIN (SELECT PC1.postcode AS postcode1, PC2.postcode AS postcode2, (3959 * acos( cos( radians(PC1.lat) ) * cos( radians( PC2.lat ) ) * 
cos( radians( PC2.lng ) - radians(PC1.lng) ) + 
sin( radians(PC1.lat) ) * sin( radians( PC2.lat ) ) ) 
  ) AS distance 
FROM postcodes PC1
CROSS JOIN postcodes PC2) PostcodeDistance
ON Charities.postcode = PostcodeDistance.postcode1
AND Postcodes.postcode = PostcodeDistance.postcode2
HAVING distance < 30 
ORDER BY distance 
LIMIT 0 , 30;

这应该会为您找到 30 英里内的慈善机构

SELECT charity, Charities.postcode, PostcodeDistance.distance
FROM Charities
INNER JOIN (
SELECT PC2.postcode AS postcode2, (3959 * acos( cos( radians(PC1.lat) ) * cos( radians( PC2.lat ) ) * 
cos( radians( PC2.lng ) - radians(PC1.lng) ) + 
sin( radians(PC1.lat) ) * sin( radians( PC2.lat ) ) ) 
) AS distance 
FROM postcodes PC1
CROSS JOIN postcodes PC2
WHERE PC1.postcode='WN8'  
) PostcodeDistance
ON Charities.postcode = PostcodeDistance.postcode2
WHERE PostcodeDistance.distance < 30 
ORDER BY PostcodeDistance.distance 
LIMIT 0 , 30;

【讨论】:

太棒了——非常感谢。我有 300K 慈善机构和 3k 邮政编码(两张表都是 MyISAM)。我刚刚在 FlyspeedSQL 中试了一下 sql,耗时 109 秒——有什么办法可以加快速度? 并非如此。问题是你不得不做的计算的剪切数量。您正在进行大约 9 亿次计算,这需要时间(假设您正在计算 3k 邮政编码和 300k 慈善机构之间的距离)。但是,由于每个邮政编码有许多慈善机构,最好计算所有邮政编码之间的距离,然后将其加入慈善机构。用对此的建议修改了答案 我非常感谢您的帮助 - 我运行了您修改后的查询 - 我认为有些地方不太正确,我的测试删节慈善表(只有 30 条记录)花了 83 秒 - 当然它缺少WHERE postcode='WN8' 部分? 查询是获取所有慈善机构以及从慈善机构到每个邮政编码的距离。你能准确地输入你想要得到的英文(而不是代码)吗?您只想要最接近邮政编码的 30 个慈善机构吗?如果是这样,我添加了另一个建议。 我希望网页的用户输入邮政编码,然后将 30 个最近的慈善机构的列表显示在页面上

以上是关于从邮政编码表(MySql)获取纬度和经度并加入另一个表的主要内容,如果未能解决你的问题,请参考以下文章

从地理编码纬度和经度获取地址

Perl 获取位置(经度+纬度),加上邮政编码

如何在 python 上从经度和纬度获取邮政编码?

在不使用地图 android 的情况下从邮政编码中获取纬度和经度

使用 iPhone 的纬度和经度进行反向地理编码

从纬度/经度获取邮政编码 + 4