为什么我不能在ISNULL语句的第二部分中连接一个值?

时间:2012-09-25 17:53:34

标签: sql sql-server-2005

我已经使用CASE语句解决了这个问题,但我想知道为什么在使用ISNULL时,我可以将值连接到check_expression而不是replacement_value。这是一个例子:

create table name_test 
(
    nm          varchar(25)
    ,mid_init   varchar(1)
    ,name_type  int
)

insert into name_test values('Joe',NULL,1)
insert into name_test values('Joe','X',2)

我有这个查询。

SELECT
    n1.nm, isnull(n2.mid_init+'b',n1.mid_init) as m1,
    isnull(n1.mid_init,n2.mid_init+'b') as m2
FROM 
    name_test n1
    JOIN name_test n2 
    on n1.nm = n2.nm and n1.name_type = 1 and n2.name_type = 2

在第一个语句(m1)中,我首先使用NOT-NULL值,与'b'连接。在第二个语句(m2)中,我首先使用NULL值,因此查询应该传递给replacement_value。它确实如此,但只取第一个值,而不是连接值。

结果:

nm     m1   m2
Joe    Xb   X

经过一番调查,我看到了这个问题:

select 
    n1.nm, isnull(n2.mid_init+'b',n1.mid_init) as m1,
    isnull(n1.mid_init,'1'+ n2.mid_init+'b') as m2
from 
    name_test n1
    join name_test n2 
    on n1.nm = n2.nm and n1.name_type = 1 and n2.name_type = 2

返回

nm  m1  m2
Joe Xb  1

因此,ISNULL函数将占用整个check_expression,但如果check_expression为空,则只会占用replacement_value的第一部分。

有谁知道为什么会出现差异。另外,我用一个案例解决了 - 是否有更好的解决方案?

1 个答案:

答案 0 :(得分:4)

ISNULL继承第一个表达式的数据类型,而COALESCE根据数据类型优先级继承数据类型。 (无论如何,varchar(1)有什么意义?)

我愿意:

select n1.nm, 
COALESCE(CONVERT(VARCHAR(25), n1.mid_init),'1'+ n2.mid_init+'b') as m2
from name_test n1
join name_test n2 on n1.nm = n2.nm and n1.name_type = 1 and n2.name_type = 2;