Mysql - 距离参数搜索使用个人偏好查找中心位置距离内的所有目标

时间:2012-12-07 17:30:06

标签: mysql geospatial spatial

这是一个难以解释的问题。我能够找到半径x英里内的所有拉链码。但是,我想要做的是从tblUsers找到所有UserID,其中MaxDistance是< = x zipcode。

所以用简单的英语我想知道所有基于MaxDistance

的邮政编码范围内的人

例如我有一张桌子:

tblUsers(ID int, Maxdistance int,Zipcode varchar(5))
1|50|94129
2|25|94111
3|100|19019

在我的第二张表中:

tblTmpPlaces(ID int,Zipcode varchar(5))
1|94129

我想要做的是使用tblTmpPlaces zipcode,我希望能够说嘿用户1和2在他们的最大距离内并选择这些。但是,用户3的最大距离为100且不足以接近94129的tblTmpPlaces邮编.94129是San Fran,19019是费城。用户离San Fran超过100英里。

这是我一直用来获取距离但是它使用中心位置来查找区域内的所有内容,但它没有考虑MaxDistance。任何帮助表示赞赏。

所以基本上select ID from tblUsers where这就是我在

上绊脚石的部分
SELECT Zipcode
             FROM tblZipcodes
            WHERE (  3959
                   * acos(
                            cos(
                               radians(
                                  @XLocationParam))
                          * cos(
                               radians(
                                  x(location)))
                          * cos(
                                 radians(
                                    y(location))
                               - radians(
                                    @YLocationParam))
                        +   sin(
                               radians(
                                  @XLocationParam))
                          * sin(
                               radians(
                                  x(location)))) <= 30))

2 个答案:

答案 0 :(得分:0)

看起来你需要每个邮政编码“中心”的纬度和经度。没有它,MySQL无法计算邮政编码之间的距离。

tblZipcodeLatLong
( Zipcode   varchar(5)
, latitude  decimal(7,4)
, longitude decimal(7,4)
)

然后,您可以使用Great Circle Distance(GCD)公式计算所有Zipcodes之间的距离。

但是,对于性能,您可能不希望在每个单独的查询中执行此操作,而是要预先计算所有Zipcodes之间的距离,并将这些计算的距离存储在表中。

SELECT p1.Zipcode AS p1_Zipcode
     , p2.Zipcode AS p2_Zipcode
     , <gcd_formula> AS distance
  FROM tblZipcodeLatLong p1
 CROSS
  JOIN tblZipcodeLatLong p2

<gcd_distance>代表您的大圆距离公式,用于计算所有邮政编码之间的距离。

此表单的查询将返回您要查找的结果集:

SELECT u.*, p.*
  FROM tblTmpPlaces p
  JOIN (
         SELECT p1.Zipcode AS p_Zipcode
              , p2.Zipcode AS u_Zipcode
              , <gcd_formula> AS distance
           FROM tblZipcodeLatLong p1 
          CROSS
           JOIN tblZipcodeLatLong p2
       ) d
    ON d.p_Zipcode = p.Zipcode
  JOIN tblUsers u 
    ON u.Zipcode = d.u_Zipcode
   AND u.Maxdistance >= d.distance
 WHERE p.Zipcode = '94129'

正如我之前提到的,在每个查询中进行交叉连接操作并计算该子查询中的所有距离(别名为d)可能会产生相当大的开销。为了提高性能,您可能希望将这些结果预先计算,存储在适当的索引表中,然后将该子查询替换为对预先填充的表的引用。


注:

我在一段时间内在stackoverflow上发布的其他答案中有一个GCD公式。我会看看能不能找到它。

这里回答类似的问题:

MYSQL sorting by HAVING distance but not able to group?

答案 1 :(得分:0)

做了完全相同的事情,如果我能理解,你已经得到了邮政编码(可能在一个数组中)简单的事情是使用 sql 中的 IN 运算符找到这些邮政编码与相应用户的匹配 选择 * 来自用户 WHERE 邮政编码在 zipcodes_array 中; zipcodes_array 是你已经拥有的数组