如何在不禁用ONLY_FULL_GROUP_BY

时间:2019-04-14 10:40:35

标签: mysql sql group-by

在MySQL中禁用ONLY_FULL_GROUP_BY后,将执行以下查询。现在,我希望获得相同的结果而不禁用ONLY_FULL_GROUP_BY

之类的GROUP BY r.user_id, u.fullname, r.time_taken模式
SELECT u.fullname, ROUND(AVG(r.correct), 2) avg_correct, date_format(r.time_taken,'%d-%m-%Y') time_taken
FROM (SELECT user_id, concat( first_name, ' ', last_name) fullname from user) u
LEFT JOIN test_result r ON u.user_id = r.user_id
GROUP BY r.user_id
ORDER BY r.time_taken DESC

截屏: screenshot

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:2)

我建议将此查询写为:

SELECT CONCAT(u.first_name, ' ', u.last_name) as fullname,
       ROUND(AVG(r.correct), 2) as avg_correct,  
       DATE_FORMAT(MAX(r.time_taken), '%d-%m-%Y') as time_taken
FROM user u LEFT JOIN
     test_result r
     ON u.user_id = r.user_id
GROUP BY u.user_id, fullname
ORDER BY MAX(r.time_taken) DESC;

注意:

  • FROM子句中的子查询对查询没有帮助。这可能会阻碍优化器。
  • 不要在GROUP BY中的 second 表中的LEFT JOIN列中(除非您真的知道自己在做什么)。对于不匹配,该值为NULL
  • MySQL和MariaDB在GROUP BY子句中允许使用列别名。
  • 要使ORDER BY能够按预期工作,必须在格式化前 上使用值,而不是在格式化后。格式%d-%m-%Y并非按时间排序。

答案 1 :(得分:1)

您必须将u.fullname添加到group by子句中,这不会影响结果,因为用户的ID和全名是唯一分组的,但是对于time_taken,则必须使用any_value()

SELECT 
  u.fullname, 
  ROUND(AVG(r.correct), 2) avg_correct, 
  date_format(any_value(r.time_taken),'%d-%m-%Y') time_taken
FROM (SELECT user_id, concat( first_name, ' ', last_name) fullname from user) u
LEFT JOIN test_result r ON u.user_id = r.user_id
GROUP BY r.user_id, u.fullname
ORDER BY time_taken DESC

您可以在此处找到更多信息:MySQL Handling of GROUP BY