mysql max()和group byerror:only_full_group_by

lbsnaicq  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(367)

我对更新mysql-5.7后记录错误的mysql查询有疑问。错误是“only\u full\u group\u by”,它将在stackoverflow时被取消。
在许多答案中,都声明不禁用此选项,而是改进sql查询。
我使用的查询返回每小时计数器的最小值和最大值。

SELECT MAX( counter ) AS max, 
       MIN( counter ) AS min, 
       DATE_FORMAT(date_time, '%H:%i') AS dt 
FROM table1 
WHERE date_time >= NOW() - INTERVAL 1 DAY 
GROUP BY YEAR(date_time), MONTH(date_time), DAY(date_time), HOUR(date_time)

据我从错误消息中了解,我在“按原因”组中的“选择原因”中缺少一项。但是我恢复/删除/添加的项目并没有得到升级到mysql-5.7之前得到的结果。
我尝试对主查询进行子查询以改进sql查询。但不知何故我无法重现结果。
我错过了什么?

kadbb459

kadbb4591#

SELECT MAX( counter ) AS max, 
       MIN( counter ) AS min,
       YEAR(date_time) AS g_year,
       MONTH(date_time)AS g_month,
       DAY(date_time) AS g_day,
       HOUR(date_time) AS g_hour 
FROM table1 
WHERE date_time >= NOW() - INTERVAL 1 DAY 
GROUP BY g_year, g_month, g_day, g_hour

或者,如果您总是这样做一天,就可以消除冗余数据:

SELECT MAX( counter ) AS max, 
       MIN( counter ) AS min,
       DAY(date_time) AS g_day,
       HOUR(date_time) AS g_hour 
FROM table1 
WHERE date_time >= NOW() - INTERVAL 1 DAY 
GROUP BY g_day, g_hour
yks3o0rb

yks3o0rb2#

mysql无法确定函数依赖性。。。在GROUPBY子句中的表达式和select列表中的表达式之间。
选择列表中的非聚合表达式( DATE_FORMAT(date_time, '%H:%i') 包括分钟组件。GROUPBY子句将在一小时内将行折叠成组。所以分钟的价值是不确定的。。。我们知道会有人吵架,但不能保证是哪一个。
(问题涉及 ONLY_FULL_GROUP_BY 似乎表明我们对不确定值有了一些了解……)
最简单(最少)的修改是将表达式 Package 在 MIN 或者 MAX 功能。

SELECT MAX(t.counter)                          AS `max`
      , MIN(t.counter)                          AS `min`
      , MIN(DATE_FORMAT(t.date_time,'%H:%i'))   AS `dt`
   FROM table1 t
  WHERE t.date_time >= NOW() - INTERVAL 1 DAY 
  GROUP
     BY YEAR(t.date_time)
      , MONTH(t.date_time)
      , DAY(t.date_time)
      , HOUR(t.date_time)
  ORDER
     BY YEAR(t.date_time)
      , MONTH(t.date_time)
      , DAY(t.date_time)
      , HOUR(t.date_time)

如果希望按特定顺序返回行,则应包含 ORDER BY 并且不依赖于mysql特定的扩展或行为 GROUP BY (在将来的版本中可能会消失。)
做一件事有点奇怪 GROUP BY 年、月、日,不包括在选择列表中的值(这样做不是无效的,只是有点奇怪。天气状况 WHERE 条款是保证我们的工作时间不超过24小时 date_time .
我倾向于做 GROUP BY 在与选择列表中的非聚合相同的表达式上。如果我需要超过24小时,我会包括日期部分:

SELECT MAX(t.counter)                             AS `max`
      , MIN(t.counter)                             AS `min`
      , DATE_FORMAT(t.date_time,'%Y-%m-%d %H:00') + INTERVAL 0 DAY AS `dt`
   FROM table1 t
  WHERE t.date_time >= NOW() - INTERVAL 1 DAY 
  GROUP
     BY DATE_FORMAT(t.date_time,'%Y-%m-%d %H:00') + INTERVAL 0 DAY
  ORDER
     BY DATE_FORMAT(t.date_time,'%Y-%m-%d %H:00') + INTERVAL 0 DAY

--或者--
如果我们总是知道这只是一天的价值 date_time ,我们只想返回小时,然后我们就可以按小时分组。与“选择”列表中的表达式相同。

SELECT MAX(t.counter)                             AS `max`
      , MIN(t.counter)                             AS `min`
      , DATE_FORMAT(t.date_time,'%H:00')           AS `dt`
   FROM table1 t
  WHERE t.date_time >= NOW() - INTERVAL 1 DAY 
  GROUP
     BY DATE_FORMAT(t.date_time,'%H:00')
      , DATE_FORMAT(t.date_time,'%Y-%m-%d %H')
  ORDER
     BY DATE_FORMAT(t.date_time,'%Y-%m-%d %H')

相关问题