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

MySQL多列子查询执行失败(Error 1055)问题咨询

问题排查与解决

报错原因

单独执行子查询时,SELECT YEAR(HIREDATE), MAX(SAL) FROM emp GROUP BY YEAR(HIREDATE)是符合only_full_group_by规则的——分组列YEAR(HIREDATE)和聚合函数MAX(SAL)的组合合法。但将其放入(YEAR(HIREDATE), SAL) IN (...)结构后,MySQL查询优化器会对整个语句进行重写(比如尝试转换为关联查询或HAVING子句形式),重写过程中误判YEAR(HIREDATE)为未在GROUP BY中声明的非聚合列,从而触发1055错误。

解决方法

1. 用派生表包装子查询

通过给子查询套一层派生表,强制MySQL先生成子查询的临时结果集,再进行IN匹配,规避优化器重写的问题:

SELECT ENAME, HIREDATE, SAL 
FROM emp
WHERE (YEAR(HIREDATE), SAL) IN (
  SELECT hire_year, max_sal
  FROM (
    SELECT YEAR(HIREDATE) AS hire_year, MAX(SAL) AS max_sal
    FROM emp
    GROUP BY YEAR(HIREDATE)
  ) AS temp
);

2. 使用JOIN替代IN子查询(推荐)

JOIN方式不仅能避免优化器的误判,性能通常更优,逻辑也更直观:

SELECT e.ENAME, e.HIREDATE, e.SAL
FROM emp e
INNER JOIN (
  SELECT YEAR(HIREDATE) AS hire_year, MAX(SAL) AS max_sal
  FROM emp
  GROUP BY YEAR(HIREDATE)
) t 
ON YEAR(e.HIREDATE) = t.hire_year AND e.SAL = t.max_sal;

3. 临时关闭only_full_group_by(不推荐)

仅适合临时测试场景,长期使用会违反SQL标准,可能导致其他查询结果异常:

-- 临时移除ONLY_FULL_GROUP_BY
SET sql_mode = REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', '');

-- 执行目标查询
SELECT ENAME, HIREDATE, SAL 
FROM emp
WHERE (YEAR(HIREDATE), SAL) IN (
  SELECT YEAR(HIREDATE), MAX(SAL)
  FROM emp
  GROUP BY YEAR(HIREDATE)
);

-- 恢复原有sql_mode(可选)
SET sql_mode = CONCAT('ONLY_FULL_GROUP_BY,', @@sql_mode);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 03:42:51