三值逻辑(Three Value Logic)
对于需求查出含NULL值的数据中,有所有user不等于root的账号:
正确方法一:select name from customer where referee_id !=2 or referee_id IS NULL; // != 等同 <>
正确方法二:select name from customer where referee_id NOT IN (2) or referee_id IS NULL; //NOT IN
正确方法三: select name from customer where ifnull(referee_id,0)<>2
正确方法四:select name from customer where id not in (select id from customer where referee_id=2)
错误方法:select name from customer where referee_id !=2;
错误方法:select name from customer where referee_id !=2 or referee_id = null;
在关系型数据库中,由于NULL值的存在,导致逻辑表达式存在三种值:TRUE/FALSE/UNKNOW。
![复制代码](https://common.cnblogs.com/images/copycode.gif)
SELECT '999'=NULL AS C1, '999'='111' AS C2, '999'='999' AS C3; +------+----+----+ | C1 | C2 | C3 | +------+----+----+ | NULL | 0 | 1 | +------+----+----+ 1 row in set (0.00 sec)
![复制代码](https://common.cnblogs.com/images/copycode.gif)
NULL值表示不确定或未知的值,因此NULL值是否等于或不等于某个特定值,只能使用IS NULL或IS NOT NULL来判断。
NULL值处理
在大部分场景中,NULL值不等于任何值包括NULL值,但在下列场景中设定NULL值相等:
1、对于唯一索引,仅允许唯一索引列存在一个NULL值。 2、对于GROUP BY和DISTINCT操作,所有NULL值当做同一组处理。 3、对于ORDER BY操作,所有NULL值被当做"最小值"排序在一起。
UNKNOW值处理
对于逻辑表达式计算后得到的UNKNOW值,在不同场景中处理方式不同:
1、在WHERE/ON/HAVING三类筛选操作中,UNKNOW值被当做FALSE处理。 2、在CHECK约束中,UNKNOW值被当做TRUE处理,CHECK约束仅对CHCK表达式为FALSE的记录返回错误。
UNKNOW值踩坑
很多生产案例是由于忽略UNKNOW值或对UNKNOW值处理不当导致,研发人员或DBA经常将逻辑表达式结果按照"非黑即白"(TURE OR FALSE)的结果去处理。
场景1、等值判断和不等值判断随意"转换",如:
![复制代码](https://common.cnblogs.com/images/copycode.gif)
表TB1表结构为(ID INT PRIMARY KEY,C1 VARCHAR(20))
A、查询满足C1等于'ABC'的记录,使用SELECT * FROM TB1 WHERE C1='ABC'
B、查询满足C1不等于'ABC'的记录,使用SELECT * FROM TB1 WHERE C1<>'ABC'
C、查询满足C1不等于'ABC'的记录,使用SELECT * FROM TB1 WHERE NOT(C1='ABC')
D、查询满足C1不等于'ABC'的记录,使用SELECT * FROM TB1 WHERE ID NOT IN (SELECT ID FROM TB1 WHERE C1='ABC')
如果表TB1上有C1列为NULL的记录,则上面操作B和操作C返回相同的查询结果,但操作B和操作D返回不同的查询结果,那么那个操作才真正满足业务需求呢?
![复制代码](https://common.cnblogs.com/images/copycode.gif)
场景2、IN子查询和NOT IN子查询随意“切换”, 如:
mysql.user表存放用户账号信息 A、使用 select host,user from mysql.user where user not in ('root')可以查出所有user不等于NULL且不等于root的账号。 A、使用select host,user from mysql.user where user not in ('root',NULL);不能查出所有user不等于ROOT和不等于NULL的用户,因为NOT IN条件中包含NULL,所有值包括NULL值在NOT IN(NULL)操作时,都会返回UNKNOW,因此该查询会返回空集。标签:三值,UNKNOW,--,user,Logic,C1,NULL,where,id From: https://www.cnblogs.com/ds521/p/16943149.html