【问题标题】:Why can't I SELECT column_name IS NULL in SQL Server?为什么我不能在 SQL Server 中选择 column_name IS NULL?
【发布时间】:2015-10-13 09:48:34
【问题描述】:
create table MyTable (id int not null primary key, val int);

insert into MyTable (id, val) values (1, 1), (2, null);

select id, val, val is null as val_null from MyTable;

这当然是有效的 SQL。然而,SQL 服务器在“is null”处抱怨语法无效。为什么会这样?

SQL fiddle:http://sqlfiddle.com/#!6/73f9a/1(我在 SQL Server 2008 和 2014 上试过这个,但在 2014 年我不断收到“糟糕”消息,表明 SQL Fiddle 有问题,可能是暂时的。)

【问题讨论】:

  • 有效的 SQL 怎么样?你想做什么? WHERE val IS NULL?
  • 具体来说,它如何无效?
  • SQL Server 没有布尔数据类型(就能够定义这种类型的列/变量而言)。因此,您希望val_null 的数据类型是什么?
  • 当您使用 MySQL 之前,您会注意到它的一些语法变化在其他 DBMS 中是不允许的 :-)
  • 顺便说一句,如果您抱怨没有布尔数据类型的 DBMS 完全疯狂,至少 Oracle、DB2 和 Teradata 也不支持它。 MySQL的BOOLEAN实际上是一个TINYINT(1),它使用0代表FALSE1代表TRUE,但也允许-128127sqlfiddle.com/#!9/1f047/2)之间的任何其他值,很好运气好使用那个糟糕的实现:-)

标签: sql sql-server null


【解决方案1】:

is null 只能写在条件中,mssql 不支持条件到布尔值的转换。所以,你需要IIF 语句才能得到结果:

select id, val, IIF(val is null, 1, 0) as val_null 
from MyTable;

IIF 适用于 SQL Server 2012+ 版本。

【讨论】:

  • 您应该对此添加一些解释,为什么会这样等等,但这是正确的答案...
  • 当然这给出了一个合理的结果,但它并没有解释为什么我的原始语法还没有这样做。
  • @Hammerite ahhhh...因为,tsql没有这样的语法,你不能像你有问题的那样写
  • @Backs 添加 IIF 与 SQL Server 2012+ 一起使用的信息
【解决方案2】:

您可以使用ISNULLCOALESCE 更改NULL 的值:

LiveDemo

select id, val, ISNULL(val, 0) as val_null
from MyTable;

或:

select id, val, COALESCE(val, 0) as val_null
from MyTable;

select id, val, CASE 
                 WHEN val IS NULL THEN 0
                 ELSE val
               END as val_null
from MyTable;

说明:

你不能直接在SELECT中使用IS NULLpredicate

是一个计算结果为 TRUE、FALSE 或 UNKNOWN 的表达式。谓词 用于 WHERE 子句和 HAVING 子句的搜索条件, FROM 子句的连接条件和其他结构 布尔值是必需的。

改用ISNULL/COALESCE 函数。或者用CASE 包装谓词。

【讨论】:

    【解决方案3】:

    您不能简单地SELECT val IS NULL 的原因是因为从这种类型的表达式(谓词)到值没有隐式强制。就此而言,它与SELECT val > 10 没有什么不同。你可以看到documentation,它明确表示:

    (谓词,包括 IS [NOT] NULL...) 是一个计算结果为 TRUE、FALSE 或 UNKNOWN 的表达式。谓词用于 WHERE 子句和 HAVING 子句的搜索条件、FROM 子句的连接条件以及其他需要布尔值的构造。

    当您想使用谓词选择一个值时,您应该明确说明它,例如,使用IIF()

    SELECT id, val, IIF(val IS NULL , 'True', 'False') AS val_null 
    FROM MyTable;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      • 2013-07-08
      • 2013-07-31
      • 2014-09-04
      • 1970-01-01
      • 2022-11-21
      相关资源
      最近更新 更多