MySQL删除非最大日期行时遇Error Code:1241错误求助
解决MySQL Error 1241: Operand should contain 1 column(s)的问题
这个报错我太熟悉了!咱们先搞清楚问题出在哪,再给你几个靠谱的解决方案。
错误原因拆解
你写的SQL里,id IN (...)里面的子查询用了select *,这会返回campanya_baja表的所有列,但IN运算符要求括号里的子查询只能返回单一列(也就是你要匹配的id列)。数据库收到多列结果,自然就抛出了「操作数应该只有1列」的错误。
快速修正原SQL
最简单的修改就是把子查询里的select *改成select id,让它只返回需要匹配的id列:
DELETE FROM campanya_baja WHERE id IN ( SELECT id FROM campanya_baja WHERE fecha_campanya_baja != (SELECT MAX(fecha_campanya_baja) FROM campanya_baja) GROUP BY id_contacto, id_usuario, id_emp_dato, fecha_campanya_baja );
不过这里要提一句:如果你的MySQL开启了ONLY_FULL_GROUP_BY模式(默认是开启的),这个GROUP BY写法可能会报错,因为id不在GROUP BY列表里也没有聚合函数。所以更稳妥的是用下面两种方案。
方案1:用窗口函数(MySQL 8.0+推荐)
窗口函数是处理这类「保留每组最新记录」场景的最优解,逻辑清晰还不容易出错:
DELETE cb FROM campanya_baja cb JOIN ( SELECT id, -- 按用户/联系人/企业分组,每组内按日期倒序排,给记录标序号 ROW_NUMBER() OVER ( PARTITION BY id_contacto, id_usuario, id_emp_dato ORDER BY fecha_campanya_baja DESC ) AS rn FROM campanya_baja ) ranked ON cb.id = ranked.id -- 删除序号大于1的记录(也就是非每组最新的记录) WHERE ranked.rn > 1;
这个写法的核心是:给每个id_contacto, id_usuario, id_emp_dato组合里的记录按日期从新到旧排号,只保留排号为1的那条最新记录,其他全部删除。
方案2:关联子查询(兼容低版本MySQL)
如果你的MySQL版本低于8.0,不支持窗口函数,可以用关联子查询来实现:
DELETE FROM campanya_baja cb WHERE EXISTS ( SELECT 1 FROM campanya_baja cb2 -- 匹配同组的记录 WHERE cb2.id_contacto = cb.id_contacto AND cb2.id_usuario = cb.id_usuario AND cb2.id_emp_dato = cb.id_emp_dato -- 存在比当前记录日期更新的同组记录 AND cb2.fecha_campanya_baja > cb.fecha_campanya_baja );
逻辑很直白:只要某条记录存在同组且日期更新的记录,就把它删掉,剩下的自然就是每组的最新记录。
内容的提问来源于stack exchange,提问作者Jose Gimeno
相关产品推荐
相关产品推荐

