Как я могу перебрать массив при усреднении значений одного элемента и сохранить только недавно усредненное поле в php?

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

Структура БД:

id | name    | tscore            | added 

int| string  | float(100 or less)| date(2014-01-01 16:34:22)
while($row = mysql_fetch_assoc($getChartData)){ // Data from MySQL
    $added_date = explode(' ',$row['added']); // Date formate 2014-01-01 16:34:22
    $chartData[] = array(
        'id'     => $row['name'],
        'tscore' => $row['tscore'],
        'added'  => $added_date[0] // Here I take the month only
    );
}
if($_POST['range'] == 'month'){
    foreach($chartData as $key => $value){
        $added = explode('-',$chartData[$key]['added']);
        $count = 1;
        foreach($chartData as $key2 => $value2){
            $added2 = explode('-',$chartData[$key2]['added']);
            if($chartData[$key]['id'] === $chartData[$key2]['id'] && $added[1] === $added2[1]){ // if user is the same and the month is the same, add the scores together, increment counter, and unset 2nd instance
                $chartData[$key]['tscore'] = ((float)$chartData[$key]['tscore'] + (float)$chartData[$key2]['tscore']);
                $count++;
                unset($chartData[$key2]);
            }     
        }
        $chartData[$key]['tscore'] = ($chartData[$key]['tscore']/$count); // Average all the scores for the month.
    }
}

Проблема в том, что этот метод удаляет все элементы массива $chartData. Любая помощь приветствуется.

2 ответа

Решение

Вы должны попытаться решить это с MySQL. Попробуйте что-то вроде этого (замените 'your_scores_table' на имя вашей таблицы):

SELECT
    Score.name, 
    AVG(Score.tscore) AS `avg`,
    CONCAT(YEAR(Score.added), '-', MONTH(Score.added)) AS `year_month`
FROM 
    your_scores_table AS Score
GROUP BY 
    Score.name ASC, 
    YEAR(Score.added) DESC, 
    MONTH(Score.added) DESC
;

Ваша логика неверна. Вы перебираете один и тот же массив дважды. Это означает, что следующее if всегда будет иметь значение true, что означает, что элемент массива всегда будет неустановленным

//This will always be true
if($chartData[$key]['id'] === $chartData[$key2]['id'] && $added[1] === $added2[1]){

Возможно, вам будет проще создать другой массив, в котором вы сохраните свои результаты. Что-то вроде

$aScores = array();
$count = 1;
foreach($chartData as $key => $value){

    //Add score to a different array
    $aScores[$value['name']]['tscore'] = (($aScores[$value['name']]['tscore'] + $value['tscore']) / $count);

    $count++;
}

Также я бы посмотрел на функцию MySQL AVG. Вы можете использовать это, чтобы избавить вас от необходимости делать это в PHP

Другие вопросы по тегам