我需要获得
$product['stars']
的总和,以便我可以用它来求平均值。当我尝试使用它时,我没有在阵列上使用它?我也相信这是一个字符串。需要转换成INT吗?
$categories = array();
while ($row_rsCategories = mysqli_fetch_assoc($res)) {
$product_array = array();
$product_array_query = mysqli_query($mysqli,"SELECT id, user_id, client_id, comments, stars FROM reviews WHERE user_id = '" . $row_rsCategories['userId'] . "'");
while ($product_array_fetch = mysqli_fetch_array($product_array_query)) {
$product_array[] = array(
"id" => $product_array_fetch['user_id'],
"comments" => $product_array_fetch['comments'],
"stars" => $product_array_fetch['stars']
);
}
$categories[] = array(
'id' => $row_rsCategories['userId'],
'name' => $row_rsCategories['usersName'],
'products' => $product_array,
);
}
foreach ($categories as $category) {
?>
<div class="col-md-4">
<div id = "user-square">
<?php
echo $category['name'];
?>
</br>
<?php foreach($category['products'] as $product) {
echo $product['stars'];
?> </br>
<?php }
您可以通过将
array_sum
与 array_map
组合来做到这一点:
$starsum = array_sum(array_map(function($x) { return $x['stars']; }, $product_array));
但是您也可以在构建结果数组时计算总和:
$starsum = 0;
$rowcount = 0;
while($product_array_fetch = mysqli_fetch_array($product_array_query)) {
$product_array[] = array("id"=>$product_array_fetch['user_id'],"comments"=>$product_array_fetch['comments'],"stars"=>$product_array_fetch['stars']);
$starsum += $product_array_fetch['stars'];
$rowcount++;
}
$categories[] = array(
'id' => $row_rsCategories['userId'],
'name' => $row_rsCategories['usersName'],
'products' => $product_array,
'avgstars' => ($rowcount == 0) ? 0 : $starsum / $rowcount
);
无需将值转换为整数,当您对它们使用算术函数时,PHP 会自动执行此操作。
使用嵌套循环访问数据库并不是一个好习惯。理想情况下,您希望单次访问数据库并收集所有必需的数据。在这种情况下,如果您想要忽略未给予评论的用户,请使用 INNER JOIN;如果您想要包含未给予评论的用户,请使用 LEFT JOIN。您无条件声明
$product_array
表明您应该使用 LEFT JOIN。
无需手动从结果集对象中记录
fetch()
——只需在对象上使用foreach()
并访问数据,就好像每行都是关联数组一样。
至于按
userId
分组,如果你没有积累comments
字符串,我建议你使用MySQL的AVG()
聚合函数。但是,由于您需要更细致的功能,因此需要手动操作来填充评论子数组并跟踪星级和评论计数。我将演示如何将引用推入结果数组,然后仅修改这些引用以更新必要的字段。
代码:(PHPize Demo使用我自己的示例输入数据)
$sql = <<<SQL
SELECT userId,
usersName,
comments,
stars
FROM cats
LEFT JOIN reviews ON cats.userId = reviews.user_id
ORDER BY cats.usersName, cats.userId
SQL;
$result = [];
foreach ($mysqli->query($sql) as $row) {
if (!isset($ref[$row['userId']])) {
$ref[$row['userId']] = [
'id' => $row['userId'],
'name' => $row['usersName'],
'comments' => $row['stars'] === null ? [] : [$row['comments']], // if a review, create single-element array
'stars' => $row['stars'] === null ? [] : [$row['stars']], // if a review, create single-element array
'reviews' => $row['stars'] === null ? 0 : 1, // if a review, start count at 1
'starSum' => $row['stars'],
'average' => $row['stars'],
];
$result[] = &$ref[$row['userId']];
} else {
$ref[$row['userId']]['comments'][] = $row['comments']; // push new value into subarray
$ref[$row['userId']]['stars'][] = $row['stars']; // push new value into subarray
++$ref[$row['userId']]['reviews']; // increment review count
$ref[$row['userId']]['starSum'] += $row['stars']; // add new value to stored sum
$ref[$row['userId']]['average'] = $ref[$row['userId']]['starSum'] / $ref[$row['userId']]['reviews']; // calculate new average
}
}
var_export($result);
这应该为您提供向最终用户显示相关数据所需的每一条数据。
我的样本数据的输出:
array (
0 =>
array (
'id' => '7',
'name' => 'Alan',
'comments' =>
array (
0 => 'super-ordinary',
),
'stars' =>
array (
0 => '3',
),
'reviews' => 1,
'starSum' => '3',
'average' => '3',
),
1 =>
array (
'id' => '5',
'name' => 'Bill',
'comments' =>
array (
0 => 'pretty not bad',
1 => 'what a stinker',
),
'stars' =>
array (
0 => '4',
1 => '1',
),
'reviews' => 2,
'starSum' => 5,
'average' => 2.5,
),
2 =>
array (
'id' => '1',
'name' => 'Chad',
'comments' =>
array (
0 => 'super mega wow',
),
'stars' =>
array (
0 => '5',
),
'reviews' => 1,
'starSum' => '5',
'average' => '5',
),
3 =>
array (
'id' => '3',
'name' => 'Dave',
'comments' =>
array (
0 => 'absolutely ace',
1 => 'twas very good',
),
'stars' =>
array (
0 => '5',
1 => '4',
),
'reviews' => 2,
'starSum' => 9,
'average' => 4.5,
),
4 =>
array (
'id' => '2',
'name' => 'Ned',
'comments' =>
array (
0 => 'a nice quality',
1 => 'I was very meh',
),
'stars' =>
array (
0 => '4',
1 => '2',
),
'reviews' => 2,
'starSum' => 6,
'average' => 3,
),
5 =>
array (
'id' => '4',
'name' => 'Newt',
'comments' =>
array (
),
'stars' =>
array (
),
'reviews' => 0,
'starSum' => NULL,
'average' => NULL,
),
6 =>
array (
'id' => '6',
'name' => 'Norton',
'comments' =>
array (
),
'stars' =>
array (
),
'reviews' => 0,
'starSum' => NULL,
'average' => NULL,
),
)