| 
                         我们发现结果是空,查询不到任何数据,这是为什么 ?这里 NULL 又开始作怪了,我们一步一步来看看究竟发生了什么。 
- -- 1. 执行子查询,获取年龄列表 
 - SELECT * FROM t_student 
 - WHERE age NOT IN(43, NULL, 25); 
 -  
 - -- 2. 用NOT 和IN 等价改写NOT IN 
 - SELECT * FROM t_student 
 - WHERE NOT age IN (43, NULL, 25); 
 -  
 - -- 3. 用OR 等价改写谓词IN 
 - SELECT * FROM t_student 
 - WHERE NOT ( (age = 43) OR (age = NULL) OR (age = 25) ); 
 -  
 - -- 4. 使用德· 摩根定律等价改写 
 - SELECT * FROM t_student 
 - WHERE NOT (age = 43) AND NOT(age = NULL) AND NOT (age = 25); 
 -  
 - -- 5. 用<> 等价改写 NOT 和 = 
 - SELECT * FROM t_student 
 - WHERE (age <> 43) AND (age <> NULL) AND (age <> 25); 
 -  
 - -- 6. 对NULL 使用<> 后,结果为 unknown 
 - SELECT * FROM t_student 
 - WHERE (age <> 43) AND unknown AND (age <> 25); 
 -  
 - -- 7.如果 AND 运算里包含 unknown,则结果不为true(参考三值逻辑的逻辑值表) 
 - SELECT * FROM t_student 
 - WHERE false 或 unknown; 
 
  
可以看出,在进行了一系列的转换后,没有一条记录在 WHERE 子句里被判断为 true 。也就是说,如果 NOT IN 子查询中用到的表里被选择的列中存在  NULL ,则 SQL 语句整体的查询结果永远是空。这是很可怕的现象! 
为了得到正确的结果,我们需要使用 EXISTS 谓词。 
- -- 正确的SQL 语句:马化腾和李彦宏将被查询到 
 - SELECT * FROM t_student_B B 
 - WHERE NOT EXISTS (  
 -     SELECT * FROM t_student_A A 
 -     WHERE B.age = A.age 
 -     AND A.city = '深圳市'  
 - ); 
 
  
执行结果如下: 
  
同样地,我们再来一步一步地看看这段 SQL 是如何处理年龄为 NULL 的行的: 
- -- 1. 在子查询里和 NULL 进行比较运算,此时 A.age 是 NULL 
 - SELECT * FROM t_student_B B 
 - WHERE NOT EXISTS (  
 -     SELECT * FROM t_student_A A 
 -     WHERE B.age = NULL 
 -     AND A.city = '深圳市'  
 - ); 
 -  
 - -- 2. 对NULL 使用“=”后,结果为 unknown 
 - SELECT * FROM t_student_B B 
 - WHERE NOT EXISTS (  
 -     SELECT * FROM t_student_A A 
 -     WHERE unknown 
 -     AND A.city = '深圳市'  
 - ); 
 -  
 - -- 3. 如果AND 运算里包含 unknown,结果不会是true 
 - SELECT * FROM t_student_B B 
 - WHERE NOT EXISTS (  
 -     SELECT * FROM t_student_A A 
 -     WHERE false 或 unknown 
 - ); 
 -  
 - -- 4. 子查询没有返回结果,因此相反地,NOT EXISTS 为 true 
 - SELECT * FROM t_student_B B 
 - WHERE true; 
 
                          (编辑:泰州站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |