Sql 为什么可以';在ISNULL语句的第二部分连接一个值吗?

Sql 为什么可以';在ISNULL语句的第二部分连接一个值吗?,sql,sql-server-2005,Sql,Sql Server 2005,我已经用CASE语句解决了这个问题,但是我想知道为什么在使用ISNULL时,我可以将一个值连接到check\u表达式,而不是替换值。下面是一个例子: 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

我已经用CASE语句解决了这个问题,但是我想知道为什么在使用
ISNULL
时,我可以将一个值连接到check\u表达式,而不是替换值。下面是一个例子:

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
)中,我首先使用空值,因此查询应该传递到替换值。确实如此,但只接受第一个值,而不接受连接的值

结果:

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\u表达式
,但如果
check\u表达式
为null,它将只接受
替换值的第一部分


有人知道为什么会有差异吗。另外,我用一个case解决了这个问题-有更好的解决方案吗?

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;

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;

谢谢你,亚伦。这是一个更好的方法。但是,我仍然很好奇为什么会发生这种情况,因为它对两个参数的处理方式不同。如果您只说
ISNULL(mid_init,其他一些表达式)
,那么这两个表达式都转换为第一个表达式的数据类型。由于
mis\u init
varchar(1)
,因此输出(和第二个表达式)也将是
varchar(1)
。什么是
转换(varchar(1),'xyz')
x
。谢谢-我明白我的错误了。谢谢你的帮助,亚伦。这是一个更好的方法。但是,我仍然很好奇为什么会发生这种情况,因为它对两个参数的处理方式不同。如果您只说
ISNULL(mid_init,其他一些表达式)
,那么这两个表达式都转换为第一个表达式的数据类型。由于
mis\u init
varchar(1)
,因此输出(和第二个表达式)也将是
varchar(1)
。什么是
转换(varchar(1),'xyz')
x
。谢谢-我明白我的错误了。谢谢你的帮助。