You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

适配ONLY_FULL_GROUP_BY:GROUP BY查询调整问题咨询

适配MySQL ONLY_FULL_GROUP_BY的查询调整方案

核心规则

启用ONLY_FULL_GROUP_BY后,SELECT子句中的每一列必须满足以下两个条件之一:

  1. 出现在GROUP BY子句中(作为分组依据)
  2. 被聚合函数(如COUNT()、SUM()、MAX()等)包裹

关于SELECT *的疑问

是的,不能直接用SELECT *配合GROUP BY。因为SELECT *会返回所有列,其中必然包含不在GROUP BY里的非聚合列,违反ONLY_FULL_GROUP_BY规则,直接触发报错。


逐个示例解答

示例1

原查询:

SELECT headhunter, COUNT(*) AS amount
FROM table
GROUP BY headhunter

无需调整。amount是COUNT(*)生成的聚合结果,不属于表的原始列,不需要加入GROUP BY。只有表的原始列才需要考虑是否在GROUP BY中。

示例2

原查询:

SELECT *, departure, DATE_FORMAT(departure,'%d.%m.%y') AS departure2
FROM table
WHERE carnumber1=''
GROUP BY shipid
ORDER BY departure DESC

问题说明:

  • SELECT *包含大量不在GROUP BY(shipid)中的列,违反规则;
  • departure是原始列,既不在GROUP BY里也未被聚合,违规;
  • departure2基于违规的departure生成,同样不符合要求。

修正方案:

  1. 移除SELECT *,只保留业务需要的列;
  2. 若需要departure的值,用聚合函数明确指定取分组内的哪一个值(比如MAX(departure)取最新值);
  3. departure2要基于聚合后的departure计算;
  4. ORDER BY可直接用聚合后的departure,无需强制加入shipid;
  5. PHP循环用到的列,要么加入GROUP BY,要么用聚合函数处理后加入SELECT,不需要全部加入ORDER BY(除非排序需要)。

修正后示例(取分组内最新的departure):

SELECT shipid, MAX(departure) AS departure, DATE_FORMAT(MAX(departure),'%d.%m.%y') AS departure2
FROM table
WHERE carnumber1=''
GROUP BY shipid
ORDER BY departure DESC

示例3

原查询:

SELECT customer
FROM table
WHERE carnumber1!=''
GROUP BY customer
ORDER BY customer ASC

无需调整。SELECT的列与GROUP BY的列完全一致,符合规则。

示例4

原查询:

SELECT customer
FROM table
WHERE carnumber1!=''
AND preparation>date_sub(NOW(),INTERVAL 6 MONTH)
GROUP BY customer
ORDER BY customer ASC

无需调整。WHERE子句的过滤条件不影响GROUP BY规则,只要SELECT的列在GROUP BY中即符合要求。

示例5

原查询:

SELECT customer
FROM table
GROUP BY customer
HAVING MAX(preparation)<=date_sub(NOW(), INTERVAL 6 MONTH)
ORDER BY customer ASC

无需调整。HAVING中使用MAX(preparation)是合法的聚合操作,preparation不需要加入SELECT或GROUP BY,只要SELECT的列在GROUP BY中即可。

示例6

原查询:

SELECT DATE_FORMAT(delivery,'%M %Y'), COUNT(*) AS amount, SUM(purchase_price) AS summed
FROM table
GROUP BY MONTH(delivery), YEAR(delivery)

无需调整。DATE_FORMAT(delivery,'%M %Y')与GROUP BY中的MONTH(delivery), YEAR(delivery)逻辑等价(同一分组的delivery年月相同,格式化结果一致),SUM(purchase_price)是聚合函数,完全符合规则。不需要把delivery加入SELECT,也不需要把purchase_price加入GROUP BY。


额外提示

  1. 若需要分组内某列的特定值(如最新、最早),要明确使用对应聚合函数;ANY_VALUE()可取分组内任意值,适合不关心具体取值的场景;
  2. 无法开启ONLY_FULL_GROUP_BY测试时,可手动检查查询中的非聚合列,确保要么在GROUP BY中,要么被聚合函数包裹;
  3. 严格按规则编写查询,避免依赖MySQL旧版本的宽松模式,升级后即可平稳过渡。

内容的提问来源于stack exchange,提问作者WeekendCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 16:02:01