如何用MySQL从给定用户名列表中筛选出数据库不存在的用户
需求与问题
我有如下用户名列表:
username abc xyz cde
执行SQL语句:
select username from users where username in ('abc','xyz','cde')
返回结果为abc和xyz。我希望通过SQL获取该列表中不存在于数据库的用户名(即本案例中的cde),尝试了以下语句,但不确定是否正确:
SELECT username FROM ( VALUES ROW(‘abc'), ROW(‘xyz'), ROW(‘cde') , ) as usernames (username) WHERE NOT exists ( SELECT username FROM user where username in (‘abc’,’xyz’,’cde') )
你的语句存在的问题
VALUES子句最后一行多了个逗号,会触发语法错误;NOT EXISTS的子查询逻辑错误:当前写法是判断user表中是否存在任何在列表里的用户,只要有一个存在,整个条件就不成立,最终会返回空结果,无法筛选出单个不存在的用户名。
正确的SQL写法
方法一:NOT EXISTS关联子查询
SELECT u.username FROM ( VALUES ROW('abc'), ROW('xyz'), ROW('cde') ) AS u(username) WHERE NOT EXISTS ( SELECT 1 FROM users db_u WHERE db_u.username = u.username )
逻辑:临时表u中的每个用户名,去数据库表users中逐一匹配,找不到对应记录的就会被筛选出来。
方法二:LEFT JOIN + IS NULL
如果觉得NOT EXISTS不够直观,也可以用左连接实现:
SELECT u.username FROM ( VALUES ROW('abc'), ROW('xyz'), ROW('cde') ) AS u(username) LEFT JOIN users db_u ON db_u.username = u.username WHERE db_u.username IS NULL
逻辑:将临时表与数据库表按用户名左连接,数据库中无匹配的记录会显示NULL,筛选出这些NULL对应的临时表用户名即可。
额外注意
- 你的SQL里用了中文单引号
‘’,实际执行时要换成英文单引号'',否则会报错; - 不同数据库的临时表写法有细微差异,比如MySQL可以用
UNION ALL构造临时表:
SELECT u.username FROM ( SELECT 'abc' AS username UNION ALL SELECT 'xyz' UNION ALL SELECT 'cde' ) AS u WHERE NOT EXISTS ( SELECT 1 FROM users db_u WHERE db_u.username = u.username )
内容的提问来源于stack exchange,提问作者zod
相关产品推荐
相关产品推荐

