使用group by with mysql时没有得到正确的结果

时间:2013-06-10 15:00:22

标签: mysql join group-by

我有3个名为用户,餐馆,评论的表。这里用户的id(主键)充当餐馆中的外键uid并且在评论表中rate_to与餐馆的uid相关联并且rate_by与用户表的id相关联。我希望所有餐馆都属于餐馆餐桌上的用户,但是从评论表中按照他们的avg_rate排序。我已经使用了这个查询。

 SELECT `Restaurant`.`id`, `Review`.`avg_rating`, `Review`.`rate_to`
 FROM `users` AS `User`
 LEFT JOIN `reviews` AS `Review` ON (`User`.`id` = `Review`.`rate_to`)
 LEFT JOIN `restaurants` AS `Restaurant` ON (`User`.`id` = `Restaurant`.`uid`) 
 WHERE  `User`.`type` = '0'  AND  `User`.`isdeleted` = '0'
 GROUP BY `Review`.`rate_to` ORDER BY `Review`.`avg_rating` DESC     

但是当我使用它时,它只给我那些在评论表中有条目的餐馆,但是我希望所有不同的餐馆餐厅餐厅在评论表中按照avg_rate排序。

请帮忙。

4 个答案:

答案 0 :(得分:1)

我可以看到这里没有使用用户表来获得结果。你可以试试这个:

SELECT `Resturant`.`id` , MAX( `Review`.`avg_rating` ) AS max_avg, `Review`.`rate_to` FROM `resturants` AS `Resturant` LEFT JOIN reviews AS Review ON ( `Resturant`.`uid` = `Review`.`rate_to` ) WHERE 1 GROUP BY `Resturant`.`id` ORDER BY `Review`.`avg_rating` DESC

答案 1 :(得分:1)

您的SELECT列表中有(非聚合的)字段,这些字段在GROUP BY中未提及。

大多数DBMS禁止这样做并且有充分的理由。 MySQL没有,因此你会得到essentially random results

答案 2 :(得分:0)

在这种情况下,我不确定左连接是否可以工作两次。也许你应该使用子查询?

答案 3 :(得分:0)

尝试按相反顺序列出,例如

 SELECT `Restaurant`.`id`, `Review`.`avg_rating`, `Review`.`rate_to`
 FROM `restaurants` AS `Restaurant` 
 LEFT JOIN `reviews` AS `Review` ON (`Review`.`rate_to` = `Restaurant`.`uid`) 
 LEFT JOIN `users` AS `User` ON (`User`.`id` = `Review`.`rate_by`)
 WHERE  `User`.`type` = '0'  AND  `User`.`isdeleted` = '0'
 GROUP BY `Restaurant`.`id` ORDER BY `Review`.`avg_rating` DESC   

那将确保你得到所有的餐馆。但是,它也不起作用,因为Review.avg_ratingReview.rate_to不是聚合函数 - 如果你需要聚合,我看不出User如何在这里发挥作用。

尝试

 SELECT `Restaurant`.`id`, AVG(`Review`.`avg_rating`)
 FROM `restaurants` AS `Restaurant` 
 LEFT JOIN `reviews` AS `Review` ON (`Review`.`rate_to` = `Restaurant`.`uid`) 
 GROUP BY `Restaurant`.`id` 
 ORDER BY AVG(`Review`.`avg_rating`) DESC   

这应该会更好,但你会包括所有已删除的用户。

为了摆脱已删除用户留下的评论,您可能需要一个子查询:

 SELECT `Restaurant`.`id`, AVG(`Review`.`avg_rating`)
 FROM `restaurants` AS `Restaurant` 
 LEFT JOIN (select r.* from `reviews` r
     JOIN `users` AS `User` ON (`User`.`id` = `Review`.`rate_by`)
     WHERE  `User`.`type` = '0'  AND  `User`.`isdeleted` = '0'
 ) AS `Review` ON (`Review`.`rate_to` = `Restaurant`.`uid`) 
 GROUP BY `Restaurant`.`id` 
 ORDER BY AVG(`Review`.`avg_rating`) DESC   

由于您没有向我们提供DDL,我没有测试过任何这些。