【问题标题】:Unexpected result in SELECT CASE WHEN NULLSELECT CASE WHEN NULL 中的意外结果
【发布时间】:2014-02-23 22:05:20
【问题描述】:

架构和数据

我有两个具有以下架构和数据的表:

#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

问题

现在,如果我从 #table1 中选择所有并离开加入 #table2,如下所示:

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
;

输出如下:

PK    TEXT
1     NULL
2     B
3     C
4     NULL
5     NULL

问题

我预计结果是:

PK    TEXT
1     a     <
2     B
3     C
4     d     <
5     e     <

那么为什么会发生这种情况(或者我做错了什么),我该如何解决这个问题?

源代码

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;

【问题讨论】:

  • 使用CASE WHEN IS NULL--forgot IS。
  • @Mihai 感谢您的评论,但这会产生incorrect syntax near the keyword 'IS' 错误。

标签: sql sql-server-2008 select-case


【解决方案1】:

在我看来,这相当于

select isnull(table2.text, table1.text) as text from ...

【讨论】:

  • 这更干净,+1。
  • 你是对的,这解决了它。但是知道为什么我的方法会失败会很有趣。
  • @Bjørn-RogerKringsjå - 正如我的回答所详述,问题在于您构建案例陈述的方式。当您执行 CASE x WHEN NULL THEN... 时,您实际上是在与 NULL 进行比较,这始终是错误的。
【解决方案2】:

你应该通过is null检查一个字段是否为空,即使你的case when在语法上是正确的,你应该使用另一个语法正确的版本。

case
  when #table2.[TEXT] is null then #table1.[TEXT]
  else #table2.[TEXT]
end

【讨论】:

    【解决方案3】:

    问题在于您构建CASE 语句的方式。 CASE x WHEN NULL THEN... 形式的任何 CASE 语句都不会像您最初预期的那样运行,因为您正在有效地执行与 NULL 的比较,这始终是错误的,在您的情况下导致总是得到 #table2.[TEXT]

    我认为你需要这样做:

    (CASE WHEN #table2.[TEXT] IS NULL THEN #table1.[TEXT] ELSE #table2.[TEXT] END) AS [TEXT]
    

    相当于COALESCE:

    COALESCE(#table2.[TEXT], #table1.[TEXT]) AS [TEXT]
    

    【讨论】:

      猜你喜欢
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 2011-08-07
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      相关资源
      最近更新 更多