处理三个表时,在查询中使用“NOT IN”运算符可能会出现问题,尤其是在处理 NULL 值时。本文演示了与使用“NOT IN”相关的风险,并提出了替代解决方案。
提供的查询旨在比较两个表,Grade 和评估,识别等级中未出现在评估中的记录。但是,当计算中不存在指定的名称(“JOHN”)时,查询将无法返回任何输出。
解决此问题,如果用于过滤数据的子查询可能包含 NULL 值,请避免使用“NOT IN”。相反,请考虑使用“NOT EXISTS”或左连接。
让我们说明一下使用“NOT IN”的潜在危险:
创建 mStatus 和 people 表包含样本数据:
create table mStatus ( id int auto_increment primary key, status varchar(10) not null ); insert mStatus (status) values ('single'),('married'),('divorced'),('widow'); create table people ( id int auto_increment primary key, fullName varchar(100) not null, status varchar(10) null );
Chunk1:
truncate table people; insert people (fullName,`status`) values ('John Henry','single'); select * from mstatus where `status` not in (select status from people);
预期输出:3 行
Chunk2:
truncate table people; insert people (fullName,`status`) values ('John Henry','single'),('Kim Billings',null); select * from mstatus where status not in (select status from people);
意外输出:0 rows
第二个块意外地没有返回任何行,因为SQL的三值逻辑。当子查询包含 NULL 值时,“NOT IN”表达式的计算结果可能为 UNKNOWN,从而导致所有行被过滤掉。
解决此问题问题,使用“LEFT JOIN”或“NOT EXISTS":
select s.status from mstatus s left join people p on p.status=s.status where p.status is null
select s.status from mstatus s where not exists (select 1 from people where people.status=s.status)
这些替代解决方案正确处理 NULL 值并提供所需的输出。
以上是为什么 MySQL 的'NOT IN”会因三个表和 NULL 而失败,有哪些更好的替代方案?的详细内容。更多信息请关注PHP中文网其他相关文章!