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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:58:42