在SQL Server查询中将NULL替换为0


175

我已经开发了一个查询,并且在前三列的结果中得到了NULL。我该如何替换0

  Select c.rundate, 
    sum(case when c.runstatus = 'Succeeded' then 1 end) as Succeeded, 
    sum(case when c.runstatus = 'Failed' then 1 end) as Failed, 
    sum(case when c.runstatus = 'Cancelled' then 1 end) as Cancelled, 
    count(*) as Totalrun from
    (    Select a.name,case when b.run_status=0 Then 'Failed' when b.run_status=1 Then 'Succeeded'
    when b.run_status=2 Then 'Retry' Else 'Cancelled' End as Runstatus,
    ---cast(run_date as datetime)
                cast(substring(convert(varchar(8),run_date),1,4)+'/'+substring(convert(varchar(8),run_date),5,2)+'/'          +substring(convert(varchar(8),run_date),7,2) as Datetime) as RunDate
    from msdb.dbo.sysjobs as a(nolock) inner join msdb.dbo.sysjobhistory as b(nolock) 
    on a.job_id=b.job_id
    where a.name='AI'
    and b.step_id=0) as c
    group by 
    c.rundate

@ user2246674前三列:sum(成功时为c.runstatus ='成功',然后为1结束时的情况),sum(成功情况,当c.runstatus ='Failed',则为1结束时,然后为1结束) =“已取消”,然后是1个结束),已取消
Bhaskar Mishra,

闪闪发光,Oracle与使用NVL或NVL2不同,不是非零...请检查oracle-base.com/articles/misc/null-related-functions
KingRider

Answers:


375

如果您想null用其他内容替换可能的列,请使用IsNull

SELECT ISNULL(myColumn, 0 ) FROM myTable

如果它首先为null,则它将在myColumn中放置一个0。


2
对于那些很少使用SQL Server 2000或2005的用户,ISNULL是SQL Server 2008及更高版本。
凯尔(Kyle)2016年

1
对于多列,我必须多次写入ISNULL还是有类似ISNULL(myColumns,0)的东西?
Flaudre '17

@Kyle:这是不正确的:从个人经验(和一本书的报价)来看,我可以确认(至少)从SQL Server 2000开始就支持ISNULL,甚至可能更早。
Heinzi '18

@Flaudre:您必须多次写入ISNULL,因为每个输出列必须具有自己的表达式。
Heinzi

这也有助于我在SQL Server 2016中获得准确的结果。非常感谢,您刚刚度过了我的一天@phadaphunk
PatsonLeaner

83

您可以使用这两种方法,但有一些区别:

SELECT ISNULL(col1, 0 ) FROM table1
SELECT COALESCE(col1, 0 ) FROM table1

比较COALESCE()和ISNULL():

  1. ISNULL函数和COALESCE表达式具有相似的用途,但行为可能不同。

  2. 因为ISNULL是一个函数,所以它仅被评估一次。如上所述,可以多次评估COALESCE表达式的输入值。

  3. 结果表达式的数据类型确定是不同的。ISNULL使用第一个参数的数据类型,COALESCE遵循CASE表达式规则,并返回优先级最高的value的数据类型。

  4. 对于ISNULL和COALESCE,结果表达式的NULLability不同。ISNULL返回值始终被认为是不可为空的(假定返回值是不可为空的),而具有非空参数的COALESCE被视为可为NULL。因此,表达式ISNULL(NULL,1)和COALESCE(NULL,1)尽管等效,但具有不同的可空性值。如果要在计算列中使用这些表达式,创建键约束或确定标量UDF的返回值以便可以对其进行索引(如以下示例所示),则这会有所不同。

-该语句失败,因为PRIMARY KEY无法接受NULL值-并且col2的COALESCE表达式的可为空性得出的值为NULL。

CREATE TABLE #Demo 
( 
    col1 integer NULL, 
    col2 AS COALESCE(col1, 0) PRIMARY KEY, 
    col3 AS ISNULL(col1, 0) 
); 

-此语句成功,因为-ISNULL函数的可空性评估为AS NOT NULL。

CREATE TABLE #Demo 
( 
    col1 integer NULL, 
    col2 AS COALESCE(col1, 0), 
    col3 AS ISNULL(col1, 0) PRIMARY KEY 
);
  1. ISNULL和COALESCE的验证也不同。例如,将ISNULL的NULL值转换为int,而对于COALESCE,则必须提供数据类型。

  2. ISNULL仅采用2个参数,而COALESCE采用可变数量的参数。

    如果您需要了解更多信息,请参见msdn 的完整文档


23

coalesce

coalesce(column_name,0)

虽然,求和时when condition then 1,您可以轻松地更改sumcount-例如:

count(case when c.runstatus = 'Succeeded' then 1 end) as Succeeded,

Count(null)返回0,而sum(null)返回null。)


10

当您说前三栏时,您是说您的SUM专栏吗?如果是这样,请添加ELSE 0到您的CASE报表中。在SUM一个的NULLNULL

sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded, 
sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed, 
sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled, 


7

用此代码包装您的专栏。

 ISNULL(Yourcolumn, 0)

也许检查为什么你得到空值


6

使用COALESCE,它返回第一个非空值,例如

SELECT COALESCE(sum(case when c.runstatus = 'Succeeded' then 1 end), 0) as Succeeded

如果返回,将成功设置为0 NULL


1

在您的case语句中添加else,以便在未找到测试条件的情况下默认为零。目前,如果未找到测试条件,则将NULL传递给SUM()函数。

  Select c.rundate, 
    sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded, 
    sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed, 
    sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled, 
    count(*) as Totalrun from
    (    Select a.name,case when b.run_status=0 Then 'Failed' when b.run_status=1 Then 'Succeeded'
    when b.run_status=2 Then 'Retry' Else 'Cancelled' End as Runstatus,
    ---cast(run_date as datetime)
                cast(substring(convert(varchar(8),run_date),1,4)+'/'+substring(convert(varchar(8),run_date),5,2)+'/'          +substring(convert(varchar(8),run_date),7,2) as Datetime) as RunDate
    from msdb.dbo.sysjobs as a(nolock) inner join msdb.dbo.sysjobhistory as b(nolock) 
    on a.job_id=b.job_id
    where a.name='AI'
    and b.step_id=0) as c
    group by 
    c.rundate

1

如果您使用的是Presto,AWS Athena等,则没有ISNULL()函数。而是使用:

SELECT COALESCE(myColumn, 0 ) FROM myTable

0
sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded, 
sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed, 
sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled, 

这里的问题是,如果没有else语句,则当运行状态不是列描述中指定的状态时,您必然会收到Null。向Null添加任何内容都会导致Null,这就是此查询的问题。

祝好运!


0

通过遵循先前的答案,我在SQL Server数据库中丢失了列名,但是遵循此语法也帮助我保留了ColumnName

ISNULL(MyColumnName, 0) MyColumnName
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.