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

使用SET赋值子查询结果时触发「Subquery returns more than 1 row」错误求助

这个问题我之前也碰到过,本质原因是你用SET给单个变量赋值时,子查询返回了多个结果——而MySQL的普通用户变量只能存储单个值,自然就触发了"Subquery returns more than 1 row"的报错。给你几个实用的解决思路:

方案1:跳过变量,直接执行删除(最简洁高效)

既然你的最终目的是删除这些孤立记录,完全可以跳过赋值变量这一步,直接把查询逻辑整合到DELETE语句里:

DELETE FROM text_fields 
WHERE study_id NOT IN (SELECT id FROM studies);

这样既避免了变量的问题,又减少了中间步骤,执行效率也更高。

方案2:用GROUP_CONCAT把多值拼成字符串变量

如果一定要用变量来存储这些ID,可以用GROUP_CONCAT将多个ID拼接成逗号分隔的字符串,之后用FIND_IN_SET来匹配:

-- 先把所有符合条件的ID拼成字符串
SET @text_field_ids := (
    SELECT GROUP_CONCAT(tf.id) 
    FROM text_fields as tf 
    WHERE tf.study_id NOT IN (select id from studies)
);

-- 用FIND_IN_SET匹配字符串里的ID
DELETE FROM text_fields 
WHERE FIND_IN_SET(id, @text_field_ids);

⚠️ 注意:GROUP_CONCAT有默认长度限制(默认1024字符),如果你的ID数量很多,可能会被截断。可以先执行SET SESSION group_concat_max_len = 1000000;来临时调整会话级别的长度限制。

方案3:用临时表存储多值(适合大数据量场景)

如果你的孤立记录数量非常多,用字符串变量可能有长度风险,建议用临时表来存储这些ID:

-- 创建临时表存储需要删除的ID
CREATE TEMPORARY TABLE temp_text_field_ids 
SELECT id FROM text_fields 
WHERE study_id NOT IN (SELECT id FROM studies);

-- 通过临时表执行删除
DELETE FROM text_fields 
WHERE id IN (SELECT id FROM temp_text_field_ids);

-- 用完可以删除临时表(可选,会话结束会自动销毁)
DROP TEMPORARY TABLE temp_text_field_ids;

临时表的优势是没有长度限制,处理大量数据时更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:23:00