根据邮政编码选择记录及其在MySQL中的半径

时间:2016-05-24 04:25:07

标签: mysql sql zipcode postal-code postal

下面是我的postal表,其中包含一些记录。实际上,该表包含所有城市和所有邮政编码。

id    city                 postalcode    latitude          longitude
 1    Drogteropslagen      7705 PA       52.61666700       6.50000000
 2    Coevorden            7740 AA       52.66666700       6.75000000
 3    Emmen                7812 TN       52.78333300       6.90000000
 4    Emmer-Compascuum     7881 PZ       52.81666700       7.05000000
 5    Nieuw-Dordrecht      7885 AA       52.75000000       6.96666700

下面是我的company表格及其邮政编码以及每家公司能够提供服务的公里半径。

id   company_name   city              postalcode   radius   latitude      longitude
1    A              Emmen             7812 TN      10       52.78333300   6.90000000
2    B              Nieuw-Dordrecht   7885 AA      5        52.75000000   6.96666700
3    C              Drogteropslagen   7705 PA      25       52.61666700   6.50000000
4    D              Foxhol            9607 PR      0        53.16666700   6.71666700
5    E              Westerbroek       9608 PA      15       53.18333300   6.68333300

我想选择特定邮政编码的公司,例如7740 AA住在邮政编码区域加上公司的半径。请注意,特定邮政编码可能并不总是存在于company表中,但始终存在于postal表中。如何编写SQL查询来选择那些公司。

2 个答案:

答案 0 :(得分:1)

此方法在包含感兴趣公司的单个记录的子查询与包含每个公司的子查询之间执行CROSS JOIN。该查询使用Haversine公式计算两公司之间的距离(以公里为单位)(您可以阅读更多关于here的内容)。

您可以使用此查询来获取邮政编码7740 AA半径20公里范围内的所有公司。

SELECT t2.company_name,
    (6371 * acos(cos(radians(t1.lat1)) * cos(radians(t2.lat2)) 
    * cos(radians(t2.lng2) - radians(t1.lng1)) + sin(radians(t1.lat1)) * sin(radians(t2.lat2)))) AS distance
FROM
(
    SELECT p.latitude AS lat1, p.longitude AS lng1
    FROM postal p
    WHERE p.postalcode = '7740 AA'
) t1
CROSS JOIN
(
    SELECT c.company_name, p.latitude AS lat2, p.longitude AS lng2
    FROM company c INNER JOIN postal p
        ON c.postalcode = p.postalcode
) t2
HAVING distance < 20

答案 1 :(得分:0)

Tim Biegeleisen的询问激励我找到如下工作解决方案。

SELECT t2.company_name,
       (6371 * acos(cos(radians(t1.lat1)) * cos(radians(t2.lat2)) 
       * cos(radians(t2.lng2) - radians(t1.lng1)) + sin(radians(t1.lat1)) *       
       sin(radians(t2.lat2)))) AS distance, 
       t2.radius 
FROM
    (
     SELECT p.latitude AS lat1, p.longitude AS lng1
     FROM postal p 
     WHERE p.postalcode = '7894 AA'
    ) t1
    CROSS JOIN
    (
     SELECT c.company_name, p.latitude AS lat2, p.longitude AS lng2,
            c.radius 
     FROM company c 
     INNER JOIN postal p
     ON c.postalcode = p.postalcode
    ) t2
HAVING distance < t2.radius

根据上述查询,距离不会与固定的公里数(例如20或50公里)相比,而是与每家公司的动态半径(公里)相比。