如何在SQL中筛选从未成功登录的用户(排除含成功记录的uID)
从未成功登录用户的SQL查询解决方案
问题分析
你需要筛选的是所有记录中从未出现过auth_field='true'的uID——只要某个uID有一条成功登录记录,就完全排除。你的原语句存在两个核心问题:
HAVING (auth_field) = 'false'不合法:GROUP BY uID后,auth_field不属于聚合字段,无法直接在HAVING中单独引用,数据库要么报错,要么返回不可靠的随机结果。- 仅添加
WHERE NOT auth_field = 'true'无法满足需求:这个条件只是过滤掉成功登录的记录,但如果某个uID既有成功又有失败记录,过滤后剩下的失败记录依然会被GROUP BY保留,无法排除该uID。
正确的SQL写法
方法1:NOT EXISTS子查询(逻辑清晰,推荐)
如果只需要获取符合条件的uID列表:
SELECT DISTINCT uID FROM database d1 WHERE NOT EXISTS ( SELECT 1 FROM database d2 WHERE d2.uID = d1.uID AND d2.auth_field = 'true' )
如果需要同时统计每个用户的登录失败次数:
SELECT uID, COUNT(uID) AS fail_login_count FROM database d1 WHERE NOT EXISTS ( SELECT 1 FROM database d2 WHERE d2.uID = d1.uID AND d2.auth_field = 'true' ) GROUP BY uID
逻辑:直接定位所有不存在对应auth_field='true'记录的uID,确保该用户从未成功登录。
方法2:GROUP BY + HAVING聚合判断
利用字符串字典序特性('true'排序优先级高于'false'),通过MAX函数判断是否存在成功记录:
SELECT uID, COUNT(uID) AS fail_login_count FROM database GROUP BY uID HAVING MAX(auth_field) = 'false'
逻辑:如果某个uID的所有auth_field都是'false',MAX结果就是'false';只要有一条'true'记录,MAX结果就会是'true',该uID会被自动排除。
方法3:LEFT JOIN排除法
SELECT DISTINCT d1.uID FROM database d1 LEFT JOIN database d2 ON d1.uID = d2.uID AND d2.auth_field = 'true' WHERE d2.uID IS NULL
如果需要统计失败次数:
SELECT d1.uID, COUNT(d1.uID) AS fail_login_count FROM database d1 LEFT JOIN database d2 ON d1.uID = d2.uID AND d2.auth_field = 'true' WHERE d2.uID IS NULL GROUP BY d1.uID
逻辑:LEFT JOIN后,d2.uID IS NULL表示没有匹配到成功登录的记录,即该uID从未成功登录。
内容的提问来源于stack exchange,提问作者B2CAccount123
相关产品推荐
相关产品推荐

