2015-03-14 3 views
2

Я пытаюсь отобразить и отсортировать массив по средству, созданному с использованием данных из базы данных. Я извлекаю три переменные из базы данных и создаю среднее из этих значений. Это значение затем помещается в новый массив, который нужно сортировать вместе с остальными данными базы данных.Возможно ли создать вызов базы данных за пределами требуемого цикла?

Я правильно понял, что наличие SQL-запроса внутри цикла - отличная идея? (Проблема с производительностью?)

Есть ли альтернатива, доступная? Я приложил код ниже:

^database connection/query string to retrieve all data... 
$result = $stmt_business_list->fetchAll(PDO::FETCH_ASSOC); 

$items = array(); 
    foreach($result as $row){ 

    $single_business_id = $row['id']; 
    $name = $row['name']; 
    //Query to get ALL the service, value and quality ratings for certain business 
    $test_query = "SELECT * FROM rating WHERE business_id = $single_business_id"; 
    $test_query_stmt = $dbh->prepare($test_query); 
    $test_query_stmt->execute(); 
    $test_row = $test_query_stmt->fetchAll(PDO::FETCH_ASSOC); 
    $total_value = $total_quality = $total_service = 0; 

     foreach($test_row as $review) 
     { 
      $total_value += $review['value']; 
      $total_quality += $review['quality']; 
      $total_service += $review['service']; 
     } 

    $bayesian_value = (($set_site_average_review_count * $set_site_average_review_score) + $total_value)/($set_site_average_review_count + $business_review_count); 
    $bayesian_quality = (($set_site_average_review_count * $set_site_average_review_score) + $total_quality)/($set_site_average_review_count + $business_review_count); 
    $bayesian_service = (($set_site_average_review_count * $set_site_average_review_score) + $total_service)/($set_site_average_review_count + $business_review_count); 
    $average_bayesian_rating = ($bayesian_value + $bayesian_quality + $bayesian_service)/3; 
    $average_bayesian_rating = $average_bayesian_rating; 

     array_push($items, array(
     "id"=>"$single_business_id", 
     "name"=>"$name", 
     "value"=>"$total_value", 
     "quality"=>"$total_quality", 
     "service"=>"$total_service", 
     "average"=>"$average_bayesian_rating")); 

    echo 
    'Name: '.$name.'<br> 
    Value: '.$total_value.'<br> 
    Quality: '.$total_quality.'<br> 
    Service: '.$total_service.'<br> 
    Average: '.$average_bayesian_rating.'<br><br>'; 
    } 
} 

страница будет разделена на отдельном постраничный сценарий и будет отображать только 6 объектов, в то время, но со временем это может измениться, так что у меня глаз на производительности так много как я могу.

+0

Вы правы, запрос, выполняемый в цикле, станет узким местом для производительности. можно сделать все это с помощью одного запроса sql, расширив исходный запрос, который получает бизнес-список, присоединившись к таблице рейтингов и используя функцию AVG от MySQL, и GROUP BY. – flauntster

+0

Итак, чтобы получить сервис, ценность и качество из исходного запроса, просто выполните вычисления в цикле вместо этого? Хм! Я попробую! – potts

+0

Фактически функция AVG в mysql может использоваться для вычисления средних оценок, и если вы ищете общий рейтинг и количество оценок для каждого бизнеса, ознакомьтесь с функциями SUM и COUNT. Пусть база данных сделает для вас работу только в одном запросе :) – flauntster

ответ

1

SQL-агрегатные запросы созданы для такого рода вещей.

Используйте этот запрос, чтобы подвести итоги

SELECT b.name, b.id, 
     SUM(value) total_value, 
     SUM(quality) total_quality, 
     SUM(service) total_service, 
     COUNT(*)  review_count, 
     avg_reviews_per_biz 
    FROM business b 
    JOIN ratings r ON b.id = r.business_id 
    JOIN (
      SELECT COUNT(DISTINCT business_id)/COUNT(*) avg_reviews_per_biz 
      FROM ratings 
     ) a ON 1=1      
    GROUP BY b.name, b.id, avg_review_per_biz 

Это даст вам одну строку для каждого бизнеса, показывая суммированные рейтинги и количество оценок. Этот набор результатов будет иметь следующие столбцы:

name   business name 
    id   business id 
    total_value sum of value ratings for that business 
    total_quality sum of quality ditto 
    total_service sum of service ditto 
    review_count number of reviews for business "id" 
    avg_reviews_per_biz avg number of reviews per business 

Последний столбец имеет то же значение для всех строк вашего запроса.

Затем вы можете перебирать эти строки по одному бизнесу за один раз, выполняя статистические вычисления.

Я не могу сказать по вашему вопросу, где вы получаете переменные типа $ set_site_average_review_count, поэтому я не могу помочь с этими вычислениями.

Вы обнаружите, что SQL-агрегатный запрос очень эффективен.

+0

А я просто понял, re пытаюсь сделать - Не уверен, как я буду работать в среднем по каждому бизнесу, на данный момент я работаю над этим по формуле вне запроса – potts

+0

Упс, опечатка в 'average_review_per_biz'. Исправлена. –

+0

Запрос выполняется с корректировкой опечаток, но среднее значение является неправильным, поэтому я решил использовать форму байесовского языка, что, я полагаю, не может быть сделано внутри запроса? – potts