使用IN关键字仍触发Subquery returns more than 1 row错误求助
解决IN关键字下仍报Subquery returns more than 1 row的问题
嘿,我帮你拆解下这个问题:你虽然用了IN,但里面嵌套的IF函数有个致命限制——它只能返回单个值,可你在to_='group'和第三个分支里的子查询都返回了多行结果,这就直接触发了错误,因为IF根本没法处理多行输出,自然没法给IN提供有效的匹配集合。
下面是修正后的查询语句,我把逻辑重新梳理了一遍:
修正后的SQL代码
SELECT * FROM `message` WHERE `seen`='0' AND `receiver_delete`='0' AND `till_date` IS NULL AND ( -- 当to_是user时,直接匹配固定ID (`to_`='user' AND `id_receiver`='36') -- 当to_是group时,用子查询返回的所有ID匹配 OR (`to_`='group' AND `id_receiver` IN ( SELECT `id` FROM (SELECT * FROM `user_position` ORDER BY `id`) `user_position`, (SELECT @pv := '100') INITIALISATION WHERE FIND_IN_SET(`parent_id`, @pv) > 0 AND @pv := concat(@pv, ',', `id`) )) -- 其他情况(to_既不是user也不是group),匹配用户所属的消息组ID OR (`to_` NOT IN ('user','group') AND `id_receiver` IN ( SELECT `message_group`.`id` FROM `message_group` LEFT JOIN `message_group_member` ON `message_group_member`.`id_group`=`message_group`.`id` WHERE `message_group_member`.`id_user`='36' )) );
核心调整说明
- 我把原来嵌套在
IF里的逻辑拆成了三个独立的OR分支:每个分支先判断to_的取值,再用IN去匹配对应的子查询结果,彻底避开了IF只能返回单个值的限制。 - 把
seen、receiver_delete、till_date这些公共过滤条件提到了外面,既让逻辑更清晰,也能减少重复判断,提升查询效率。 - 每个分支的条件更明确,MySQL执行时可以更快地定位到对应的匹配规则。
小补充:如果你的to_字段只有user和group两种取值,那第三个分支的to_ NOT IN ('user','group')可以直接去掉,简化成OR id_receiver IN (...)就行,根据你的实际业务场景调整。
内容的提问来源于stack exchange,提问作者user8800617
相关产品推荐
相关产品推荐

