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

NOT IN子查询无结果求助:获取bus_user_perms表中不在分组结果的数据

解决NOT IN查询无结果的问题

这个问题很常见,根源在于SQL的三值逻辑以及NOT IN对NULL值的特殊处理方式。当你的子查询返回的结果集中包含NULL的Perm_id时,NOT IN会直接返回空结果——因为任何值和NULL比较都会得到UNKNOWN,而NOT IN要求所有比较结果都为TRUE才会返回行,只要有一个UNKNOWN,整个条件就不成立。

第一步:验证问题原因

先检查你的子查询是否包含NULL值:

SELECT COUNT(*) 
FROM (
    SELECT Perm_id 
    FROM bus_user_perms 
    GROUP BY Perm_username, Perm_BusArId
) sub_query
WHERE Perm_id IS NULL;

如果这个查询返回大于0的数字,那就坐实了是NULL导致的问题。

解决方案

这里提供三种可靠的替代方案,都能避开NOT IN的NULL陷阱:

方案1:在子查询中排除NULL值

直接过滤掉子查询里的NULL,让NOT IN可以正常工作:

SELECT * 
FROM `bus_user_perms` 
WHERE `Perm_id` NOT IN (
    SELECT `Perm_id` 
    FROM `bus_user_perms` 
    GROUP BY `Perm_username`, `Perm_BusArId`
    WHERE `Perm_id` IS NOT NULL -- 新增这行排除NULL
);

方案2:使用LEFT JOIN + IS NULL

这是处理这类排除查询的经典写法,逻辑清晰且不受NULL影响:

SELECT bup.*
FROM `bus_user_perms` bup
LEFT JOIN (
    SELECT `Perm_id` 
    FROM `bus_user_perms` 
    GROUP BY `Perm_username`, `Perm_BusArId`
) sub ON bup.Perm_id = sub.Perm_id
WHERE sub.Perm_id IS NULL;

原理是:将原表和子查询结果左连接,那些在子查询中没有匹配到的行(也就是你要找的61条),sub.Perm_id会是NULL,通过这个条件就能筛选出来。

方案3:使用NOT EXISTS

NOT EXISTS是更推荐的写法之一,它的逻辑是“不存在匹配子查询条件的记录”,天然不受NULL影响:

SELECT bup.*
FROM `bus_user_perms` bup
WHERE NOT EXISTS (
    SELECT 1
    FROM `bus_user_perms` bup_sub
    WHERE bup_sub.Perm_username = bup.Perm_username
      AND bup_sub.Perm_BusArId = bup.Perm_BusArId
      AND bup_sub.Perm_id = bup.Perm_id
    GROUP BY bup_sub.Perm_username, bup_sub.Perm_BusArId
);

额外提示

你的原查询中,GROUP BY Perm_username, Perm_BusArId后直接选择Perm_id,在严格SQL模式下会报错(因为Perm_id既不在GROUP BY列表中,也没有使用聚合函数)。如果你的数据库允许这种写法,它会返回每个分组中随机的一条Perm_id。如果你想明确获取每个分组的第一条/最后一条Perm_id,建议加上聚合函数,比如MIN(Perm_id)或MAX(Perm_id):

SELECT MIN(Perm_id) AS Perm_id 
FROM `bus_user_perms` 
GROUP BY `Perm_username`, `Perm_BusArId`

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:00:34