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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:20:51