From my perspective this is equivalent of
select isnull(table2.text, table1.text) as text from ...
Вопрос
Schema and data
I have two tables with the following schema and data:
#table1:
create table #table1(
PK int IDENTITY(1,1) NOT NULL,
[TEXT] nvarchar(50) NOT NULL
);
PK TEXT
1 a
2 b
3 c
4 d
5 e
#table2:
create table #table2(
PK int IDENTITY(1,1) NOT NULL,
FK int NOT NULL,
[TEXT] nvarchar(50) NOT NULL
);
PK FK TEXT
1 2 B
2 3 C
Problem
Now, if I select all from #table1
and left join #table2
like this:
select
#table1.PK,
(case #table2.[TEXT] when NULL then #table1.[TEXT] else #table2.[TEXT] end) as [TEXT]
from
#table1
left join
#table2 on #table2.FK = #table1.PK
;
the output are as following:
PK TEXT
1 NULL
2 B
3 C
4 NULL
5 NULL
I expected the result to be:
PK TEXT
1 a <
2 B
3 C
4 d <
5 e <
So why does this happen (or what am I doing wrong) and how can I fix this?
Source code
if (OBJECT_ID('tempdb..#table1') is not null) drop table #table1;
if (OBJECT_ID('tempdb..#table2') is not null) drop table #table2;
create table #table1(PK int IDENTITY(1,1) NOT NULL, [TEXT] nvarchar(50) NOT NULL);
create table #table2(PK int IDENTITY(1,1) NOT NULL, FK int NOT NULL, [TEXT] nvarchar(50) NOT NULL);
insert into #table1 ([TEXT]) VALUES ('a'), ('b'), ('c'), ('d'), ('e');
insert into #table2 (FK, [TEXT]) VALUES (2, 'B'), (3, 'C');
select
#table1.PK,
(case #table2.[TEXT] when NULL then #table1.[TEXT] else #table2.[TEXT] end) as [TEXT]
from
#table1
left join
#table2 on #table2.FK = #table1.PK
;
drop table #table1;
drop table #table2;
Решение
From my perspective this is equivalent of
select isnull(table2.text, table1.text) as text from ...
Другие советы
You should check whether a field is null or not by is null
, even though your case when
is syntactically correct, you should use the other syntactically correct version.
case
when #table2.[TEXT] is null then #table1.[TEXT]
else #table2.[TEXT]
end
The problem is the way you have constructed your CASE
statement. Any CASE
statement of the form CASE x WHEN NULL THEN...
is not going to behave as you might initially expect as you are effectively performing a comparison with NULL, which is always false, in your case resulting in always getting #table2.[TEXT]
.
I think you'd need to do:
(CASE WHEN #table2.[TEXT] IS NULL THEN #table1.[TEXT] ELSE #table2.[TEXT] END) AS [TEXT]
which is equivalent to COALESCE
:
COALESCE(#table2.[TEXT], #table1.[TEXT]) AS [TEXT]