Php 在MySQL中查找十进制列上最接近的匹配项

Php 在MySQL中查找十进制列上最接近的匹配项,php,mysql,geolocation,match,Php,Mysql,Geolocation,Match,下午, 我很难理解这个问题。我有一个MySQL表,其中列出了英国邮政编码及其经度和纬度值。我希望能够在表上进行搜索,找到与给定长/宽对最近的邮政编码 我尝试使用的查询是: "SELECT id, outcode AS thecode, @la := MATCH(lat) AGAINST(?) AS score_lat, @ln := MATCH(lng) AGAINST(?) AS score_lng, @la + @ln AS score_total FROM postcodes ORDER

下午,

我很难理解这个问题。我有一个MySQL表,其中列出了英国邮政编码及其经度和纬度值。我希望能够在表上进行搜索,找到与给定长/宽对最近的邮政编码

我尝试使用的查询是:

"SELECT id, outcode AS thecode, @la := MATCH(lat) AGAINST(?) AS score_lat, @ln := MATCH(lng) AGAINST(?) AS score_lng, @la + @ln AS score_total FROM postcodes ORDER BY score_total DESC LIMIT 10
但是,这只返回看似随机的邮政编码,例如Lat:55.775549和Long:-4.047556

Array
(
[0] => Array
    (
        [id] => 929
        [thecode] => FK14
        [score_lat] => 0
        [score_lng] => 0
        [score_total] => 0
    )

[1] => Array
    (
        [id] => 2785
        [thecode] => UB3
        [score_lat] => 0
        [score_lng] => 0
        [score_total] => 0
    )

[2] => Array
    (
        [id] => 993
        [thecode] => G70
        [score_lat] => 0
        [score_lng] => 0
        [score_total] => 0
    )

[3] => Array
    (
        [id] => 2849
        [thecode] => WC2B
        [score_lat] => 0
        [score_lng] => 0
        [score_total] => 0
    )

[4] => Array
    (
        [id] => 1057
        [thecode] => GU29
        [score_lat] => 0
        [score_lng] => 0
        [score_total] => 0
    )

[5] => Array
    (
        [id] => 2913
        [thecode] => WS13
        [score_lat] => 0
        [score_lng] => 0
        [score_total] => 0
    )

[6] => Array
    (
        [id] => 1121
        [thecode] => HP20
        [score_lat] => 0
        [score_lng] => 0
        [score_total] => 0
    )

[7] => Array
    (
        [id] => 1185
        [thecode] => IG6
        [score_lat] => 0
        [score_lng] => 0
        [score_total] => 0
    )

[8] => Array
    (
        [id] => 1249
        [thecode] => IV25
        [score_lat] => 0
        [score_lng] => 0
        [score_total] => 0
    )

[9] => Array
    (
        [id] => 1313
        [thecode] => KA8
        [score_lat] => 0
        [score_lng] => 0
        [score_total] => 0
    )
)
数据库的架构为:

CREATE TABLE `postcodes` (
  `id` int(11) NOT NULL auto_increment,
  `outcode` varchar(4) NOT NULL,
  `lat` varchar(20) NOT NULL,
  `lng` varchar(20) NOT NULL,
  PRIMARY KEY  (`id`),
  FULLTEXT KEY `lat` (`lat`),
  FULLTEXT KEY `lng` (`lng`)
) ENGINE=MyISAM AUTO_INCREMENT=2975 DEFAULT CHARSET=latin1 AUTO_INCREMENT=2975 ;
我希望有人能帮忙!如果您需要更多信息,请询问

谢谢

tip2tail

MySQL
MATCH()
函数用于全文搜索以“匹配”字符串。(因此,它返回的值为零也就不足为奇了。)

如果“最近”的意思是要计算地图上两点之间的距离(以“乌鸦一样”测量),坐标以纬度和经度(十进制度数)表示,那么确实需要使用大圆距离(GCD)计算

您可以跳过所有这些血淋淋的细节,只需利用我的实现。下面是我的一条SQL语句的SELECT列表的摘录,这个表达式计算两点之间的距离(以英里为单位)

     , ACOS(
          COS(RADIANS( d2.latitude ))
        * COS(RADIANS( d1.latitude ))
        * COS(RADIANS( d2.longitude ) - RADIANS( d1.longitude ))
        + SIN(RADIANS( d2.latitude ))
        * SIN(RADIANS( d1.latitude ))
           )*3958.82 AS distance_miles
在本例中,
d1
表示原点,
d2
表示终点。
纬度
经度
作为十进制值提供

对于
d1
有一个“已知”点,我可以通过这个表达式排序,首先得到“最近的”
d2
。(对于多个原点,我可以按
d1.id
排序,然后根据此表达式首先为每个
d1
获取最接近的
d2
。但关于我的问题,已经足够了


我从您的问题复制了查询并对其进行了修改(如下)。基本上,我删除了“分数”列,并将其替换为执行距离计算的表达式:

SELECT id
     , outcode AS thecode
     , ACOS(
           COS(RADIANS( d2.latitude ))
         * COS(RADIANS( @d1_latitude ))
         * COS(RADIANS( d2.longitude ) - RADIANS( @d1_longitude ))
         + SIN(RADIANS( d2.latitude ))
         * SIN(RADIANS( @d1_latitude ))
           )*3958.82 AS distance_miles
  FROM postcodes d2
  JOIN (SELECT @d1_latitude := ?, @d1_longitude := ?) v
 ORDER BY distance_miles LIMIT 10
在本例中,
@d1
变量(从绑定变量分配)是“已知”点的纬度和经度。对于
邮政编码
表中的每一行(为了方便起见,我将其别名为
d2
),此表达式计算表中的lat/long与“已知”点之间的距离

注意:别名为
v
的内联视图就在那里,因此您可以只绑定一次纬度,并将值分配给可以引用的用户变量。可以省略该内联视图,并且您可以看到需要在哪里绑定两次纬度

注意:这以“英里”为单位计算距离。您可以用不同的值代替
3958.82
常量,轻松获得以公里(km)为单位的距离

注意:没有必要返回距离;如果您只想按距离顺序返回10个最近的距离,则可以将该表达式放在ORDERBY子句中,例如

SELECT id
     , outcode AS thecode
  FROM postcodes d2
  JOIN (SELECT @d1_latitude := ?, @d1_longitude := ?) v
 ORDER
    BY ACOS(
           COS(RADIANS( d2.latitude ))
         * COS(RADIANS( @d1_latitude ))
         * COS(RADIANS( d2.longitude ) - RADIANS( @d1_longitude ))
         + SIN(RADIANS( d2.latitude ))
         * SIN(RADIANS( @d1_latitude ))
           )*3958.82 AS distance_miles
 LIMIT 10

如果你在寻找两点之间的距离以外的东西,请告诉我,因为在这种情况下,这个答案对你真的没有帮助。

你看过吗:你的应用程序相当简单,因为它只是距离公式的一个基本应用,但你问的是一个空间问题。你在做什么如果您实际提出的问题是距离问题,请匹配字符串。这种方法永远不会有效。@hsanders我甚至不知道从哪里开始!您能提供一些建议或示例,说明如何实现所需目标吗?谢谢tip2tail@spencer7592谢谢!我期待着阅读代码,看看我是如何可以把它放进我的项目中。t2t@spencer7592谢谢,但我不确定我是否明白。我不知道“目的地”是什么是。我正在尝试获取与用户当时所在位置最接近的邮政编码。因此,我只知道一个Lat/Long,并且有一个潜在Lat/Long列表,我想检查与他们最接近的Lat/Long???@每个人-我找到了另一种方法,通过第三方API实现这一点。我已将您的答案@spencer7592标记为正确你帮了大忙,再次感谢!