如何在LIKE %%查询中先按最近距离对MYSQL查询进行排序?

时间:2019-06-13 19:44:23

标签: php mysql

我有一个PHP代码,可以使用LIKE %%搜索MYSQL,并且工作正常。

现在,我需要向此查询添加更多内容,以便它使用 Like %% AND ORDER BY最近的经/纬度搜索MYQL数据库。

这是我的代码:

$term = $_GET['term']; 


   $sql = "SELECT * FROM YO_businesses WHERE category LIKE '%$term%'";
   $query = mysqli_query($db_conx, $sql) or die(mysqli_error($db_conx));
   $productCount = mysqli_num_rows($query);



    $records = array();

     while($row = mysqli_fetch_array($query, MYSQLI_ASSOC)){

     $records[] = $row;


      }


echo '' . json_encode($records, JSON_UNESCAPED_SLASHES) . '';

我需要在上述查询中添加类似的内容,但不确定如何:

$lon = //your longitude
$lat = //your latitude
$miles = //your search radius

$query = "SELECT *, 
( 3959 * acos( cos( radians('$lat') ) * 
cos( radians( latitude ) ) * 
cos( radians( longitude ) - 
radians('$lon') ) + 
sin( radians('$lat') ) * 
sin( radians( latitude ) ) ) ) 
AS distance FROM yourtable HAVING distance < '$miles' ORDER BY distance ASC LIMIT 0, 5" 

有人可以对此提出建议吗?

2 个答案:

答案 0 :(得分:1)

您可以使用select ST_Distance_Sphere( point(longitude1 , latitude1), point(longitude2, latitude2)) 函数来计算经纬度对之间的距离:

select

这将以米为单位提供距离。

要在where$query = " select *, ST_Distance_Sphere( point(longitude1 , latitude1), point($lon, $lat) ) as 'distance' from YO_businesses where ST_Distance_Sphere( point(longitude1 , latitude1), point($lon, $lat) ) < miles/1609.344 order by distance ASC LIMIT 0, 5"; 中都使用它,可以在两个部分中使用相同的表达式:

query = 'EXEC Test_procedure @DateFrom = ?, @DateTo = ?, @param3 = ?, @param4 = ?'

df = pd.read_sql(query, conn, params=[DateFrom, DateTo, None, None])

df

答案 1 :(得分:1)

必须适当地转义任何合并到SQL文本中的潜在不安全值,以减轻SQL注入漏洞。 https://www.php.net/manual/en/mysqli.real-escape-string.php

(更好的模式是使用绑定占位符准备的语句,但是如果我们不能做到这一点,则至少可以使这些值成为“ sql安全的”副本,并将其包含在SQL文本中

expo build:ios

要返回距$ lat,$ lon递增距离的所有行,我们可以在expo start子句中包含GCD计算,如下所示:

$ss_term = $db_conx->real_escape_string($db_conx,$term);
$ss_lat  = $db_conx->real_escape_string($db_conx,$lat);
$ss_lon  = $db_conx->real_escape_string($db_conx,$lon);

如果我们还想将计算出的距离作为结果集的一部分返回,则可以将计算结果重新定位到查询的ORDER BY列表中。

$sql = 
"SELECT b.*
   FROM YO_businesses b 
  WHERE b.category LIKE CONCAT('%" . $ss_term ."%')
  ORDER
     BY -- great circle distance calculation
        ( 3959 * ACOS( COS( RADIANS('" . $ss_lat . "') )
                     * COS( RADIANS( b.latitude ) )
                     * COS( RADIANS( b.longitude ) 
                            - RADIANS('" . $ss_lon . "') 
                          )
                     + SIN( RADIANS('" . $ss_lat . "') )
                     * SIN( RADIANS( b.latitude ) ) 
                 ) 
        ) ASC" ; 

通过SELECT列表中的值,我们可以通过相关名称(在$sql = "SELECT b.* , ( 3959 * ACOS( COS( RADIANS('" . $ss_lat . "') ) * COS( RADIANS( b.latitude ) ) * COS( RADIANS( b.longitude ) - RADIANS('" . $ss_lon . "') ) + SIN( RADIANS('" . $ss_lat . "') ) * SIN( RADIANS( b.latitude ) ) ) ) AS gc_distance FROM YO_businesses b WHERE b.category LIKE CONCAT('%" . $ss_term ."%')"; 子句中分配的别名SELECT引用该计算值

我们可以添加一个LIMIT子句来限制返回的行数,或者如果我们不希望返回gc_distance大于某个值的行,则可以在gc_distance子句之前在{ {1}}子句

ORDER BY

注意:

问题中的一些评论指出了ORDER BY子句的用法。在问题所示的SQL中,HAVING的用法有效。

在访问行时要评估的条件方面,注释必须正确,这些注释必须出现在$sql .= " HAVING gc_distance < 100 ORDER BY gc_distance ASC"; 子句或HAVING子句中。

在访问行之后,稍后在语句处理中评估HAVING子句中的条件。因为在访问行时聚合函数的结果(例如SUM(),COUNT(),AVG())不可用,所以这些结果的条件不能包含在WHERE子句中,我认为这导致了这一点错误的观念,即如果没有ON或没有聚合函数,就不能使用HAVING子句。