具有IS NULL的Case语句不按要求执行

时间:2014-01-23 23:12:47

标签: sql sql-server tsql null case

晚安,

我有以下sql代码,需要替换子查询中的NULL值。从代码中我可以看出我尝试使用ISNULL函数和case = = NULL。

有人可以帮忙吗?

Select Student_Details.STU_ID ,
       ( Select case ISNULL( s1stu_disability_type.DISABILITY_TYPE_CD , '' )
           when '' then 'NO'
           else 'YES'
         end
         from s1stu_disability_type
         Where Student_Details.STU_ID = s1stu_disability_type.STU_ID 
           and DISABILITY_TYPE_CD = '$HEAR'
       ) as 'Hearing Disability'
from S1STU_DET as Student_Details

3 个答案:

答案 0 :(得分:1)

子查询中的where子句拒绝所有行,但列DISABILITY_TYPE_CD'$HEAR'的行。因此,case语句将始终采用else路由,因为该列永远不会是null或空('')。

你究竟想做什么?

您可以更好地将查询写为

select sd.STU_ID ,
       dt.DISABILITY_TYPE_CD
from S1STU_DET             sd
join s1stu_disability_type dt on dt.STU_ID = sd.STU_D
                              and dt.DISABILITY_TYPE_CD = '$HEAR'

几乎认定学生和学生残疾之间的关系具有零对多的基数,也就是说每个学生都有零个或多个残疾。

因此,原始查询及其相关子查询将为每个学生返回1行,但根据SQL标准,绘制的运气很明显 匹配的残疾被选中子查询。

我的上述查询将为每名学生返回一行,并且匹配残疾。没有匹配残疾的学生将被排除在外。要将其更改为包括所有学生,您需要将[inner] join更改为left [outer] join。然后,每个学生将至少在结果集中表示一次。如果学生没有匹配的残疾,学生残疾表的所有列都将为“空”。

如果我怀疑你正在尝试做的是确定学生是否有听力障碍(或某种特定类型的残疾),你需要总结事物。像这样的查询可能会对你有所帮助:

select sd.STU_ID ,
       case sign(coalesce(hd.cnt,0))
       when 1 then 'YES'
       else        'NO'
       end as HAS_HEARING_DISABILITY
from S1STU_DET sd
left join ( select STU_ID ,
                   count(*) as cnt
            from s1stu_disability
            where DISABILITY_TYPE_CD = '$HEAR'
            group by STU_ID
          ) hd on hd.STU_ID = sd.STU_ID

答案 1 :(得分:0)

您不需要子查询(假设您的子查询只返回一条记录):

Select 
    Student_Details.STU_ID,
    case WHEN Student_Disability.DISABILITY_TYPE_CD IS NULL
      THEN 'NO'
      ELSE 'YES'
      END
      as 'Hearing Disability'
 from S1STU_DET as Student_Details
 LEFT JOIN s1stu_disability_type Student_Disability
    ON Student_Details.STU_ID = Student_Disability.STU_ID
    and Student_Disability.DISABILITY_TYPE_CD = '$HEAR'

答案 2 :(得分:0)

试试这个:

Select Student_Details.STU_ID ,
       IsNull(( Select case ISNULL( s1stu_disability_type.DISABILITY_TYPE_CD , '' )
           when '' then 'NO'
           else 'YES'
         end
         from s1stu_disability_type
         Where Student_Details.STU_ID = s1stu_disability_type.STU_ID 
           and DISABILITY_TYPE_CD = '$HEAR'
       ), 'No') as 'Hearing Disability'
from S1STU_DET as Student_Details

基本上,ISNULL函数必须在子查询之外,才能按照您希望的方式工作。可以这样想,如果子查询没有返回任何行,无论你是否在子查询中进行了isnull检查,输出都将为null。