我有一个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"
有人可以对此提出建议吗?
答案 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
子句。