基于NOT IN子查询与枚举值的无主键用户表SQL查询问题
解决方法:筛选无
transition='v2'记录的去重user_id 首先咱们先理清你的核心需求:要找出所有完全不存在transition='v2'记录的user_id,并且最终结果要去重。你之前的查询出错,主要是子查询的返回值不对,而且没做去重处理,才导致结果不符合预期。
正确的NOT IN写法
你需要让子查询返回所有包含transition='v2'的user_id,然后主查询排除这些user_id,同时用DISTINCT确保结果去重:
SELECT DISTINCT T.user_id FROM users T WHERE T.user_id NOT IN ( SELECT user_id FROM users WHERE transition = 'v2' );
逻辑拆解
- 子查询
SELECT user_id FROM users WHERE transition = 'v2'会精准找出所有有transition='v2'记录的用户ID(在你的测试数据里就是user_id=2) - 主查询的
NOT IN会直接排除这些用户,剩下的就是完全没有v2过渡记录的用户 DISTINCT关键字会自动去掉重复的user_id,解决你之前遇到的重复结果问题
等价优化写法(NOT EXISTS,大表场景更高效)
如果你的表数据量较大,NOT EXISTS的性能表现通常会更好,逻辑和NOT IN完全一致:
SELECT DISTINCT T.user_id FROM users T WHERE NOT EXISTS ( SELECT 1 FROM users U WHERE U.user_id = T.user_id AND U.transition = 'v2' );
针对你的测试数据验证
user_id=1的两条记录都没有transition='v2',会被保留在结果里user_id=2存在一条transition='v2'的记录,会被NOT IN/NOT EXISTS排除
最终结果正好是user_id=1,完全符合你的预期
关于枚举类型的说明
因为transition是枚举类型,直接写transition = 'v2'是完全合法的——数据库会自动识别枚举值,不需要额外的类型转换,这个条件的写法和普通字符串字段完全一致。
内容的提问来源于stack exchange,提问作者dev_medo
相关产品推荐
相关产品推荐

