需要使用MySQL和PHP满足多个条件

时间:2014-01-23 19:40:02

标签: php sql json

好的,想想一个允许用户输入多个搜索参数以查找附近餐馆的网站。这不是一个新颖的概念,但我遇到的问题是使用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));
        }
}

1 个答案:

答案 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中并在那里进行评分计算,然后按照该分数对结果数组进行排序。