SQL Server null知多少?
作者:网络转载 发布时间:[ 2016/3/9 11:12:55 ] 推荐标签:数据库
3.1 Not In与null
在下面这个查询中,where子句中使用not in来过滤数据,where子句的条件是OrderStatus not in ('Active','InActive'),我们期望结果集中包含orderstatus为'Not Active'、'NULL'这两行的数据。
select * from orders where OrderStatus not in ('Active','InActive')
这个查询中,当OrderStatus为null时, 原where子句等价于where null <>'Active' AND null<>'InActive',这变成了上文中介绍的比较运算与null的问题。where的判断结果还是null,所以该行不会出现在结果集中。而当OrderStatus为'Not Active'时,满足where筛选的为true的条件,会显示在结果集中。
终,正确答案是:只有一行。
说明:in与null的关系与此同理。
3.2 Not exists与null
现在我们还是期望结果集中包含orderstatus为'Not Active'、'NULL'这两行的数据,这次用Not exists。
在这个查询中,子查询先求出OrderStatus='Active' or OrderStatus='InActive的行,然后外部查询用not exists过滤子查询的结果,将剩下的行显示在终结果集中。
SELECT *
FROM orders AS o1
WHERE NOT EXISTS(
SELECT *
FROM orders AS o2
WHERE o1.OrderStatus = o2.OrderStatus
AND ( o2.OrderStatus = 'Active'
OR o2.OrderStatus = 'InActive'
));
为了方便理解,我们将子查询改写成自表连接的方式,
select * from orders as o2 where o1.OrderStatus=o2.OrderStatus and (o2.OrderStatus='Active' or o2.OrderStatus='InActive' ))
改写成:
SELECT *
FROM orders AS o2
INNER JOIN orders o1 ON o1.OrderStatus = o2.OrderStatus
AND ( o2.OrderStatus = 'Active'
OR o2.OrderStatus = 'InActive'
);
返回的结果集为:
然后我们再看外层查询,
外部查询期望使用not exists返回orders表中不包含子查询结果集的行,也是说,只要orders表没有子查询结果集中的行返回true,否则返回false(只有存在和不存在,没有unknown的说法)。
按照这个逻辑,orderID为3和4的行不在子查询的结果集中,因此not exists判断为true,而orderID为1和2的行已包含在子查询的结果集中,所以not exists判断为false。后根据where筛选“接受true,拒绝false和null”的原则,终只有orderID为3和4的行显示在结果集中。
说明:exists与null的关系与此同理。
3.3 Not in和Not exists的区别
not in实际上是对一个对象的比较运算,而比较存在true|false|unknow三种逻辑值。
not exsits判断某个对象存在或者不存在,它只有这两种状态,没有unknown的说法。因此相比not in而言,not exists只会有true和false这两种逻辑值。
总结:
上文介绍了null在不同场景中的含义,考虑到SQL不同的语言元素对null的不同处理方式,平常我们在写SQL语句的时候应该清晰思考自己编写的每个查询对null或三值逻辑的处理,避免出现逻辑错误。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11