评估为空校正的列

时间:2018-10-04 19:47:37

标签: sql sql-server

表1:

ID   email
A    a@gmail.com

表2:

ID   email2        email3   email4
A    a@gmail.com   null     ab@gmail.com

查询:

select T1.ID, T1.email, 
case when T1.email<>T2.email2 then T2.email2 end email2,
case when T1.email<>T2.email3 and T2.email2<>T2.email3 then T2.email3 end email3,
case when T1.email<>T2.email4 and T2.email2<>T2.email4 and T2.email3<>T2.email4 then T2.email4 end email4
from t1 
left join t2 on t1.id=t2.id

输出:

ID  email         email2   email3   email4
A   a@gmail.com   null     null     null

预期输出:

ID  email         email2   email3   email4
A   a@gmail.com   null     null     ab@gmail.com

由于email4为空,因此看来email3的计算结果为空。我想我了解Why does NULL = NULL evaluate to false in SQL server的原因,但是有没有一种简便的方法可以避免这种情况的发生?真正的查询要复杂得多,如果我在case语句中的每个变量周围添加类似isnull(value,'')的内容,以避免与空值进行比较,则会产生很多结果。

请注意,我无权更改ansi_nulls设置等

2 个答案:

答案 0 :(得分:2)

因为NULL意味着

  

我不知道。

因此,您可以尝试在每个IS NULL列中添加支票CASE WHEN

 CREATE TABLE Table1(
  ID VARCHAR(50),
  email VARCHAR(50)
);

INSERT INTO Table1 VALUES ('A','a@gmail.com');

CREATE TABLE Table2(
  ID  VARCHAR(50),
  email2 VARCHAR(50),
   email3 VARCHAR(50),
    email4 VARCHAR(50)
);



INSERT INTO Table2 VALUES ('A','a@gmail.com',null,'ab@gmail.com');

查询1

select T1.ID, T1.email, 
case when T1.email<>T2.email2  then T2.email2 end email2,
case when T1.email<>T2.email3 and T2.email2<>T2.email3 then T2.email3 end email3,
case when (T1.email<>T2.email4 OR T1.email IS NULL) and 
            (T2.email2<>T2.email4  OR T2.email2 IS NULL)  and 
            (T2.email3<>T2.email4  OR T2.email3 IS NULL)  then T2.email4 end email4
from Table1 t1 
left join Table2 t2 on t1.id=t2.id

Results

| ID |       email | email2 | email3 |       email4 |
|----|-------------|--------|--------|--------------|
|  A | a@gmail.com | (null) | (null) | ab@gmail.com |

答案 1 :(得分:1)

  

“真正的查询要复杂得多,如果我在case语句中的每个变量周围添加诸如isnull(value,'')之类的东西,以避免与空值进行比较,那可能会增加很多。寻找一种可能的简单方法

您可以ISNULL在派生表中的每一列一次,然后将其余查询保持不变:

select T1.ID, T1.email, 
case when T1.email<>T2.email2 then T2.email2 end email2,
case when T1.email<>T2.email3 and T2.email2<>T2.email3 then T2.email3 end email3,
case when T1.email<>T2.email4 and T2.email2<>T2.email4 and T2.email3<>T2.email4 then T2.email4 end email4
from t1 
left join (SELECT ID, 
                  ISNULL(email2,'') email2,
                  ISNULL(email3,'') email3,
                  ISNULL(email4,'') email4
           FROM t2) t2 on t1.id=t2.id