I’ve already solved this issue using a CASE statement, but I’m wondering why, when using ISNULL, can I concatenate a value to the check_expression but not the replacement_value. Here’s an example:
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)
I have this query.
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
In the first statement (m1), I use the NOT-NULL value first, concatenated with a ‘b’. In the second statement (m2), I use the NULL value first, so the query should pass through to the replacement_value. It does, but only takes the first value, not the concatenated value.
Result:
nm m1 m2
Joe Xb X
With a little more investigation, I see that this query:
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
returns
nm m1 m2
Joe Xb 1
So, the ISNULL function will take the entire check_expression, but if the check_expression is null, it will only take the first part of the replacement_value.
Does anyone know why there is a discrepancy. Also, I solved it with a case – is there a better solution?
ISNULLinherits the data type of the first expression, whileCOALESCEinherits the data type according to data type precedence. (What is the point ofvarchar(1)anyway?)I would do: