选择和空检查的情况

时间:2017-09-12 12:47:11

标签: sql-server tsql sql-server-2012

select a.AgentId,
       case(select acs.IsConnected
            from rmm.tblAgentConnectionStatus acs
            where acs.AgentName = a.AgentName)
        when 1 then 'True'
        when 0 then 'False'
        when null then 'False'
        end as ConnectionStatus
from Sentilan2.rmm.tblAgent a
order by AgentName asc

我有上面的内容,但是当它们在tblAgent中没有相应的行时,它会导致ConnectionStatus为空。

当列为空时,结果是否可能为False

当前输出

AgentId                                 ConnectionStatus
010D0206-5D8C-4AB1-90B6-7BD0C2773E22    True
CA4C48DD-3D2E-4948-9F93-254CDF081658    True
1DB90EE5-D96A-4071-8F51-26B3130EC6D4    NULL
ACA694D0-0C1D-45BA-80DD-273F41BD70B1    NULL
941B539B-7CA0-4472-ABCD-2777AE8B2E5D    NULL
1E7DDA4D-C119-4E47-8478-277952024FD1    NULL

我希望这些空值为假。

3 个答案:

答案 0 :(得分:3)

您可以使用coalesce()isnull()替换null的值:

select a.AgentId,
       case coalesce((select acs.IsConnected
            from rmm.tblAgentConnectionStatus acs
            where acs.AgentName = a.AgentName),0)
        when 1 then 'True'
        when 0 then 'False'
        end as ConnectionStatus
from Sentilan2.rmm.tblAgent a
order by AgentName asc

或只是else 'False'

select a.AgentId,
       case (select acs.IsConnected
            from rmm.tblAgentConnectionStatus acs
            where acs.AgentName = a.AgentName)
        when 1 then 'True'
        else 'False'
        end as ConnectionStatus
from Sentilan2.rmm.tblAgent a
order by AgentName asc

答案 1 :(得分:1)

你应该在两个表之间使用LEFT OUTER JOIN和COALESCE。

这样,您可以从tblAgent获得所需内容,但是在IsConnected为NULL或者tblAgentConnectionStatus中没有相应行的情况下为False

select 
   a.AgentId,
   case(coalesce(acs.IsConnected, 0))
      when 1 then 'True'
      else 'False'
    end as ConnectionStatus
from Sentilan2.rmm.tblAgent a
left join Sentilan2.rmm.tblAgentConnectionStatus acs
  on acs.AgentName = a.AgentName
order by a.AgentName asc

我建议的一件事是不加入AgentName。比较字符串。

在两个表之间建立一个整数外键(它是引用表中的主键)会更有效。这将使查询更快,特别是如果您索引外键。

我已在this SQLFiddle link

中证明了这一点

答案 2 :(得分:0)

空值的正确测试是is NULL。不幸的是,这需要重复when表达式中每个case子句的值。有多种方法可以避免重复相关的子查询,例如:公用表表达式(CTE)。在这种情况下,left outer join就足够了。

select a.AgentId,
       case
         when acs.IsConnected = 1 then 'True'
         when acs.IsConnected = 0 then 'False'
         when acs.IsConnected is null then 'False'
         else 'Oops: ' + Cast( acs.IsConnected as VarChar(64) )
         end as ConnectionStatus
  from Sentilan2.rmm.tblAgent as a left outer join
    rmm.tblAgentConnectionStatus as acs on acs.AgentName = a.AgentName
  order by AgentName asc;

提示:在else表达式中包含case子句以捕获任何意外值都是一个好主意。

提示:使用适当的软件(MySQL,Oracle,DB2,...)和版本标记数据库问题是有帮助的,例如: sql-server-2014。语法和功能的差异通常会影响答案。请注意,tsql会缩小选项范围,但不会指定数据库。