问题:
- 我有一个有两列的表,一个是char(1),另一个是varchar(1
- 我插入一行NULLS
- 我比较两列的值
- 我知道他们不平等
- 为什么
代码:
CREATE TABLE ss_1
(
[char] CHAR(1) ,
[varchar] VARCHAR(3)
)
INSERT INTO TimeCurrent..ss_1
( char, varchar )
VALUES ( NULL,-- char - char(1)
NULL -- varchar - varchar(3)
)
SELECT CASE WHEN S.char = S.varchar THEN 'yes'
ELSE 'no'
END AS eq2
FROM ss_1 AS S
FIDDLE:
http://sqlfiddle.com/#!6/84bc4/2/0
实际上,这是因为SQL
基于三值逻辑,其中谓词可以评估为三个不同的值:TRUE
、FALSE
和UNKNOWN
。当比较的任何部分是NULL
时,谓词求值为UNKNOWN
。这是正式的定义。示例:
1 = 1 => TRUE
1 = 2 => FALSE
1 = NULL => UNKNOWN
NULL = NULL => UNKNOWN
现在当你写:
CASE WHEN predicate THEN
只有当谓词求值为TRUE
时,它才会转到THEN
。但在您的情况下,它的评估值为UNKNOWN
。这就是它进入ELSE
部分的原因。
CREATE TABLE ss_1
(
[char] CHAR(1) ,
[varchar] VARCHAR(3)
)
INSERT INTO TimeCurrent..ss_1
( char, varchar )
VALUES ( NULL,-- char - char(1)
NULL -- varchar - varchar(3)
)
SELECT CASE WHEN coalesce(S.char, '') = coalesce(S.varchar, '') THEN 'yes'
ELSE 'no'
END AS eq2
FROM ss_1 AS S
这样的东西可能对你想要的东西有效。如前所述,null
与另一个null
值的直接比较永远不会返回相等,因为null
只是意味着没有值,因此没有可供比较的值。输入类型与此无关(如果两者都是char(1)
或char (3)
,或者其他数据类型,则情况相同)。
编辑:需要注意的一点是,如果空白是数据库中该列的有效输入,则您需要将''
替换为其他值(否则不合法),否则您最终会将数据库中的空白值与空值进行匹配,这可能没问题,也可能没问题。。。
编辑2:这实际上可能会稍微好一点,更能反映你的实际意图:
CREATE TABLE ss_1
(
[char] CHAR(1) ,
[varchar] VARCHAR(3)
)
INSERT INTO TimeCurrent..ss_1
( char, varchar )
VALUES ( NULL,-- char - char(1)
NULL -- varchar - varchar(3)
)
SELECT CASE WHEN S.char = S.varchar THEN 'yes'
CASE When S.char IS NULL and S.varchar IS NULL Then 'yes'
ELSE 'no'
END AS eq2
FROM ss_1 AS S