2017-02-01 14 views
1

SQL Server中的一個可空的BIT值有三個可能的值:null,0和1.我有兩列都是可空的BIT,我想知道它們何時「相等」,意思是NULL等於「NULL和1等於1,而0不等於NULL。但是,我所有的CASE陳述都沒有給出我想要的答案。準確地做這種比較的最好方法是什麼?如何正確比較SQL Server中的兩個可空的BIT值?

DECLARE @BitComparison TABLE 
(
    OldValue BIT, 
    NewValue BIT, 
    ActuallyEqual VARCHAR(10) 
) 

INSERT INTO @BitComparison (OldValue, NewValue, ActuallyEqual) 
VALUES 
    (null,null,'equal'), 
    (null,0,'not equal'), 
    (null,1,'not equal'), 
    (0,null,'not equal'), 
    (0,0,'equal'), 
    (0,1,'not equal'), 
    (1,null,'not equal'), 
    (1,0,'not equal'), 
    (1,1,'equal') 

SELECT * 
, CASE WHEN OldValue <> NewValue then 'not equal' else 'equal' end as 'ComparisonTestA' 
, CASE WHEN ISNULL(OldValue, 0) <> ISNULL(NewValue, 0) then 'not equal' else 'equal' end as 'ComparisonTestB' 
, CASE WHEN ISNULL(OldValue, -1) <> ISNULL(NewValue, -1) then 'not equal' else 'equal' end as 'ComparisonTestC' 
FROM @BitComparison 

鑑於上面的腳本,在沒有硬編碼ActuallyEqual列中的值的匹配在ComparisonTest列中的值。我可以添加到我的SELECT以動態匹配ActuallyEqual列嗎?

回答

3

使用IS NULLNULL檢查

CASE 
    WHEN OldValue = NewValue 
     OR (OldValue IS NULL AND NewValue IS NULL) THEN 'equal' 
    ELSE 'not equal' 
END AS 'ComparisonTestA' 
2

已經被髮布的解決方案是我能想到的最簡單的。這是一個輕微的變化:

CASE WHEN OldValue = NewValue 
     OR ISNULL(NewValue, OldValue) IS NULL THEN 'Equal' ELSE 'Not Equal' END 

但我想添加一個解釋,爲什麼每個表達式不起作用


CASE WHEN OldValue <> NewValue THEN 'not equal' ELSE 'equal' END 

會失敗,因爲NULL <> Anything,是NULL因此當其值爲NULL它將落入ELSE聲明並返回equal


CASE WHEN ISNULL(OldValue, 0) <> ISNULL(NewValue, 0) THEN 'not equal' ELSE 'equal' END 

當任一值是NULL它被替換爲0,因此當一個NULL,另一個是0兩者將被標識爲當它們不匹配。


CASE WHEN ISNULL(OldValue, -1) <> ISNULL(NewValue, -1) THEN 'not equal' ELSE 'equal' END 

這看起來像一個應該工作,但因爲ISNULL將返回的第一個參數的數據類型,-1轉換爲1(如可與SELECT CONVERT(BIT, -1)看到),因此當一個值是1而另一個是空的,這將錯誤地識別匹配。

考慮到這一點,你也可以換ISNULLCOALESCE

CASE WHEN COALESCE(OldValue, -1) = COALESCE(NewValue, -1) THEN 'equal' ELSE ' not equal' END 

由於COALESCE將具有最高優先級(INT > BIT)返回的數據類型,而不是第一個參數的數據類型。

+0

'(NULL <>任何)= Joy' – jaycer

2

這是一個有趣的替代方案,使用CONCAT()

SELECT OldValue,NewValue,ActuallyEqual 
    , Test = IIF(concat(OldValue,'-',NewValue) = concat(NewValue,'-',OldValue),'equal','not equal') 
FROM @BitComparison 

返回

OldValue NewValue ActuallyEqual Test 
NULL  NULL  equal   equal 
NULL  0   not equal  not equal 
NULL  1   not equal  not equal 
0   NULL  not equal  not equal 
0   0   equal   equal 
0   1   not equal  not equal 
1   NULL  not equal  not equal 
1   0   not equal  not equal 
1   1   equal   equal