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

子查询结果包含性对比:解决子查询返回多行错误

解决子查询返回多行报错 + 筛选覆盖指定用户所有登录日期的用户

首先,你遇到的More than one value was returned by a sub-query错误,本质是用了**单值比较运算符(比如=)**去匹配一个返回多条结果的子查询。比如如果你的子查询是获取用户123的所有登录日期,它会返回多行,数据库没法用=去匹配多个值,自然就报错了。

而且更关键的是:你要的是覆盖用户123所有登录日期的用户(还可以有更多日期),不是只要登录过其中某一天的用户,所以直接把=改成IN也满足不了需求——IN只能筛选出登录过123至少一天的用户,没法确保覆盖全部日期。

下面给你两种通用的解决方案,适用于大多数关系型数据库(MySQL、PostgreSQL、SQL Server等):

方法1:GROUP BY + HAVING 统计匹配日期数

核心思路是:先拿到用户123的所有唯一登录日期,再统计其他用户登录过的日期中,和123重合的数量是否等于123的总日期数——如果相等,说明该用户覆盖了123的所有日期。

假设你的表名为user_login_dates,字段是user_id(用户ID)和login_date(登录日期),SQL代码如下:

SELECT uld.user_id
FROM user_login_dates uld
-- 关联用户123的所有唯一登录日期
JOIN (
    SELECT DISTINCT login_date
    FROM user_login_dates
    WHERE user_id = '123'
) AS user123_dates 
ON uld.login_date = user123_dates.login_date
GROUP BY uld.user_id
-- 确保当前用户的匹配日期数等于123的总日期数
HAVING COUNT(DISTINCT uld.login_date) = (
    SELECT COUNT(DISTINCT login_date)
    FROM user_login_dates
    WHERE user_id = '123'
);

补充说明:

  • 用DISTINCT是为了避免同一用户同一天多次登录导致计数重复;
  • 如果用户123没有任何登录记录,这个查询会返回空结果(因为子查询的计数为0,HAVING条件永远不满足),符合逻辑;
  • 这个方法会自动包含那些登录过更多日期的用户,因为我们只统计和123重合的部分,只要数量达标就会被选中。

方法2:EXISTS + NOT EXISTS 双重排除

核心思路是:筛选出不存在任何一个用户123登录过但当前用户没登录的日期的用户——换句话说,就是用户123的每一个登录日期,当前用户都有记录。

SQL代码如下:

SELECT DISTINCT uld.user_id
FROM user_login_dates uld
WHERE NOT EXISTS (
    -- 查找用户123有但当前用户没有的日期
    SELECT 1
    FROM user_login_dates u123
    WHERE u123.user_id = '123'
    AND NOT EXISTS (
        SELECT 1
        FROM user_login_dates uld2
        WHERE uld2.user_id = uld.user_id
        AND uld2.login_date = u123.login_date
    )
);

补充说明:

  • 外层的DISTINCT用来去重,避免同一个用户ID多次出现;
  • 这个逻辑更直观,直接排除“漏了123某一天”的用户,剩下的就是符合要求的;
  • 同样,若用户123无登录记录,查询会返回所有用户(因为内层子查询永远找不到符合条件的日期,NOT EXISTS为真),如果需要处理这种边界情况,可以加个判断:AND EXISTS(SELECT 1 FROM user_login_dates WHERE user_id='123')。

为什么原来的查询会报错?

举个例子,如果你原来的查询是类似这样:

SELECT user_id
FROM user_login_dates
WHERE login_date = (SELECT login_date FROM user_login_dates WHERE user_id='123');

这里的子查询返回了用户123的所有登录日期(多行),而=只能匹配单个值,数据库不知道该拿哪一行去比较,所以抛出More than one value was returned by a sub-query错误。就算改成IN,也只能拿到登录过123至少一天的用户,没法满足你的核心需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:17:56