更新 MySQL 后,从 'sql_mode=only_full_group_by' 收到奇怪的 JOIN 错误

After updating MySQL, getting strange JOIN errors from 'sql_mode=only_full_group_by'

所以我刚更新到最新的 MySQL,我收到了这个错误:

Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'stats.playtime.date' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

我的table:

id    int(255)
date  datetime

我的查询:

SELECT DATE(date) + INTERVAL 1 DAY, COUNT(DISTINCT  id)
FROM  playtime
GROUP BY DATE(date)

它所做的只是告诉我有多少用户在特定日期首次加入,允许我在图表中显示此数据。

我不确定这个查询究竟有什么问题?我知道在这个新版本的 MySQL 中必须有新的语法规则,但我不确定如何在这个查询中遵循它们。有什么想法吗?

导致相同问题的第二个示例:

Table:

id                  int(11)
user                varchar(255)
course              varchar(255)
course_difficulty   varchar(255)
time_taken          int(255)

查询:

SELECT course, course_difficulty, time_taken
FROM minigame
WHERE user = 'abc'
GROUP BY course
ORDER BY time_taken LIMIT 50

COUNT(DISTINCT id) 是一个聚合函数,因此它允许出现在 select 子句中 group by。但是 DATE(date) + INTERVAL 1 DAY 不是聚合函数,它没有出现在 group by 子句中,所以这是你出错的原因。

要解决此问题,您应该将未聚合的列添加到 group by 子句中,就像此查询中的

SELECT DATE(`date`) + INTERVAL 1 DAY, COUNT(DISTINCT  id)
FROM  playtime
GRUP BY DATE(`date`) + INTERVAL 1 DAY

有关 group by 和聚合函数的更多信息,您可以在 [此处] 找到。1

在第一个示例中,MySQL 优化器不够智能,无法识别表达式 DATE(date) + INTERVAL 1 DAY 在功能上依赖于 DATE(date)。解决方法是将整个表达式包含在 GROUP BY 子句中。

在第二个例子中,MySQL 抱怨 SELECT 列表中不在 GROUP BY 子句中的非聚合,同样,因为它们在功能上不相关。

下面是一些示例 table 数据,说明了错误背后的基本原理:

id  user  course 
--  ----  ------
11  fee    win101
12  fi     win101
13  fo     win101 

当我们尝试运行这个查询时:

SELECT t.course, t.user
  FROM mytable t
 GROUP BY t.course

return可以为 user...fee、fi 或 fo 编辑三个可能的值。

如果我们使用聚合表达式代替列,

MySQL 将允许查询 运行。在此示例中,我们可以使用 MIN(t.user) 或 MAX(t.user),而 MySQL 将分别为 return "fee" 或 "fo" .

MySQL 将 运行 这个查询:

SELECT t.course 
     , MIN(t.user)  AS min_user
     , MAX(t.user)  AS max_user
     , COUNT(1)
  FROM mytable t
 GROUP BY t.course