【问题标题】:Not getting proper result when using group by with join in mysql在mysql中使用group by时没有得到正确的结果
【发布时间】:2013-06-10 15:00:21
【问题描述】:

我有 3 个表,分别命名为 users、restaurants、reviews。这里用户的 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 排序。

请帮忙。

【问题讨论】:

  • 您的参考键令人困惑。 review(rate_to) 引用餐厅(uid) 对用户(id) 的引用。你能提供你完整的表结构吗?

标签: mysql join group-by


【解决方案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

【讨论】:

  • rate_to 既不在 GROUP BY 中,也不在聚合函数下。根据实际数据,这可能是也可能不是问题,但我会做一个或另一个而不是让它“挂起”,以防万一。
【解决方案2】:

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

大多数 DBMS 都禁止这样做,这是有充分理由的。 MySQL 没有,因此您会得到essentially random results 的内容。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      尝试以相反的顺序列出它们,例如

       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,因此我没有对其中任何一个进行测试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-16
        • 1970-01-01
        • 2013-03-01
        • 1970-01-01
        相关资源
        最近更新 更多