好的,想想一个允许用户输入多个搜索参数以查找附近餐馆的网站。这不是一个新颖的概念,但我遇到的问题是使用SQL和PHP来输出满足多种条件的JSON数组。
例如,用户按距离和/或价格搜索和/或餐厅是否提供用餐,外卖和/或递送。如果用户没有指定类型,则搜索所有类型。那么,这里的问题是那些不是我将得到的结果。如果我使用价格,那么即使我指定“日语”,我仍然会获得美国,或快餐,烧烤等等多种类型...但是如果我按照我的评级排序,那么价格将不会排序适当的,如果用户想要寻找昂贵的餐馆($$$$通过“1”,$$$ = 2等等,其中4是最便宜的餐厅价格),它可能会首先显示较低的价格评级,因为评级较高比用户选择搜索...昂贵的价格等级...叹息。我怎么能期望满足所有这些条件?有任何想法吗?建议?谢谢!
这是My PHP with SQL语句:
switch ($rest_genre) {
case '':
$query = "SELECT rest_id,user_id,rest_name,lat,lng,rest_price,rest_rating,rest_genre,eat_in,take_out,delivery,
3959.0 * 5280.0 * acos(sin(radians(?)) * sin(radians(lat))
+ cos(radians(?)) * cos(radians(lat))
* cos(radians(lng) - radians(?))) as distance
FROM food_locations
WHERE rest_price >= ? AND eat_in = ? OR take_out = ? OR delivery = ?
HAVING distance <= $radius
ORDER BY rest_rating DESC";
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_param("sssiiii",$lat,$lat,$lng,$rest_price,$eat_in,$take_out,$delivery);
$stmt->execute();
$stmt->bind_result($rest_id,$user_id,$rest_name,$lat,$lng,$rest_price,$rest_rating,$rest_genre,$eat_in,$take_out,$delivery,$distance);
$stmt->store_result();
//fetch all records as they exist per filter
if( $stmt->num_rows() > 0 ) {
while ( $stmt->fetch() ) {
$row = array(
'restID' => $rest_id,
'userID' => $user_id,
'rest_name' => $rest_name,
'lat' => $lat,
'lng' => $lng,
'restPrice' => $rest_price,
'restRating' => $rest_rating,
'restGenre' => $rest_genre,
'eat_in' => $eat_in,
'take_out' => $take_out,
'delivery' => $delivery,
'distance' => $distance);
$rows['restaurants'][] = $row;
$rows['error'] .= $mysqli->error;
}
echo json_encode($rows);
} else {
echo json_encode(array('restaurants' => '', 'error' => $mysqli->error));
}
//alternative: echo json_encode(array_merge($rows, $errArray));
} else {
echo json_encode(array('error' => $mysqli->error));
}
break;
default:
$query = "SELECT rest_id,user_id,rest_name,lat,lng,rest_price,rest_rating,rest_genre,eat_in,take_out,delivery,
3959.0 * 5280.0 * acos(sin(radians(?)) * sin(radians(lat))
+ cos(radians(?)) * cos(radians(lat))
* cos(radians(lng) - radians(?))) as distance
FROM food_locations
WHERE rest_price >= ? AND rest_genre = ? AND eat_in = ? OR take_out = ? OR delivery = ?
HAVING distance <= $radius
ORDER BY rest_rating DESC";
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_param("sssisiii",$lat,$lat,$lng,$rest_price,$rest_genre,$eat_in,$take_out,$delivery);
$stmt->execute();
$stmt->bind_result($rest_id,$user_id,$rest_name,$lat,$lng,$rest_price,$rest_rating,$rest_genre,$eat_in,$take_out,$delivery,$distance);
$stmt->store_result();
//fetch all records as they exist per filter
if( $stmt->num_rows() > 0 ) {
while ( $stmt->fetch() ) {
$row = array(
'restID' => $rest_id,
'userID' => $user_id,
'rest_name' => $rest_name,
'lat' => $lat,
'lng' => $lng,
'restPrice' => $rest_price,
'restRating' => $rest_rating,
'restGenre' => $rest_genre,
'eat_in' => $eat_in,
'take_out' => $take_out,
'delivery' => $delivery,
'distance' => $distance);
$rows['restaurants'][] = $row;
$rows['error'] .= $mysqli->error;
}
echo json_encode($rows);
} else {
echo json_encode(array('restaurants' => '', 'error' => $mysqli->error));
}
//alternative: echo json_encode(array_merge($rows, $errArray));
} else {
echo json_encode(array('error' => $mysqli->error));
}
}
答案 0 :(得分:1)
另一方面,最简单的方法是计算实际满足的条件数,然后按该派生值排序,例如
SELECT IF(rest_price >= ?, 1, 0) + IF(rest_genre = ?, 1, 0) + more conditions
+ translate distance into score + other conditions ... AS score
....
ORDER BY score desc
这是一个丑陋的查询,但会先给你最高的得分位置。当然,您可以将原始值提取到PHP中并在那里进行评分计算,然后按照该分数对结果数组进行排序。