1

我有 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% 的评论计数。

谁能解释这里发生了什么?谢谢

4

1 回答 1

3

您可能希望利用 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

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

IE

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

更新:

我看到您遇到的类别 ID 和评论计数重复的问题。我已经更新了上面的查询以利用DISTINCT关键字,这应该可以解决问题。

于 2013-03-15T17:55:08.633 回答