1

我有 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

4 回答 4

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
于 2013-06-10T15:16:20.837 回答
1

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

大多数 DBMS 禁止这样做是有充分理由的。MySQL 没有,因此你会得到本质上是随机的结果

于 2013-06-10T15:17:37.703 回答
0

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

于 2013-06-10T15:08:58.667 回答
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_rating也不 Review.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,因此我没有测试任何这些。

于 2013-06-10T15:20:50.600 回答