通过一次数据库调用获取每种产品的评级和类别数量,以及产品列表

时间:2013-03-15 17:45:48

标签: mysql join count group-by

我有4个表:1个项目表,1个类别表,1个item_to_category表,以及一个审查每个项目的评论表。

项目可以分为多个类别。

我想获得一个PHP数组,其中列出了每个项目,项目所在的类别以及项目的审核次数。

这可以使用单个数据库调用吗?

此查询

    $q = 'SELECT `items`.`id` as item_id, `category`.`id` as category_id, COUNT(`review_id`) AS review_count
    FROM  `items`
    JOIN  `item_to_category` ON  `item_to_category`.`item_id` =  `items`.`id`
    JOIN  `category` ON  `category`.`id` =  `item_to_category`.`id`
    JOIN  `reviews` ON `items`.`id` = `reviews`.`item_id`
    WHERE `items`.`type` = 3
    GROUP BY `items`.`id`

返回如下行:

item_id    category_id    review_count
1          CAT1           4
2          CAT3           2

问题是,我的评论计数乘以项目所在的类别数,但查询只返回一个类别。

有人可以帮忙吗?

我基本上希望我的php数组像:

array(
    [0] => array(
        "item_id"=1,
        "categories"=>array("CAT1","CAT3"),
        "review_count"=>2
     )
    [1] => etc
)

此外: 我遵循了Mike Brant的建议,这是一个改进,但它没有100%正确地工作。查询的输出是:

item_id    category_id            review_count
1          CAT1,CAT2,CAT2,CAT1    4   <--- Incorrect number of reviews. Actual number is 2
2          CAT3,CAT3              2   <--- Correct number of reviews.
3          CAT1,CAT1,CAT1         3   <--- Correct number of reviews.

所以基本上,只有当项目属于1类时,返回的评论数才是正确的。 返回的类别几乎是正确的,但它们被实际的评论数量重复。

如果我删除评论表上的JOIN,我会获得100%正确的类别,如果我删除了类别上的JOIN,我会获得100%的评论计数。

任何人都可以解释这里发生了什么吗?感谢

1 个答案:

答案 0 :(得分:2)

您可能希望利用MySQL中的GROUP_CONCAT功能来执行此操作

SELECT `items`.`id` as item_id, GROUP_CONCAT(DISTINCT `category`.`id`) as categories, COUNT(DISTINCT `reviews`.`review_id`) AS review_count
FROM  `items`
JOIN  `item_to_category` ON  `item_to_category`.`item_id` =  `items`.`id`
JOIN  `category` ON  `category`.`id` =  `item_to_category`.`id`
JOIN  `reviews` ON `items`.`id` = `reviews`.`item_id`
WHERE `items`.`type` = 3
GROUP BY `items`.`id`

这会使您的结果集看起来像

item_id    category_id    review_count
1          CAT1,CAT2      4
2          CAT3,CAT4      2

然后,当您循环遍历结果集时,可以通过explode()将GROUP_CONCAT值转换为数组。

$result_array = array();
while($row = [WHATEVER YOUR DB FUNCTION IS HERE]) {
    $row['categories'] = explode(',', $row['categories']);
    $result_array = $row;
}

<强>更新

我在类别ID和审核计数中看到了您遇到的重复问题。我已更新上面的查询以使用DISTINCT关键字,这可以解决问题。