1

我想在 where 子句中使用 case 语句,但在下面的查询中出现错误。

where 
 (r.WeekId=@WeekId or @WeekId is null) and
 (ShiftId=@ShiftId or @ShiftId is null)
 and (placeid=@PlaceId or @PlaceId is null)
 and (r.StatusId=3)
 AND     
CASE WHEN @day = 1 THEN ((firstday=@time and (allocateddays is null or NOT (AllocatedDays  LIKE '%1%')))) 
 WHEN @day = 2 THEN ((secondday=@time and (allocateddays is null or NOT (AllocatedDays LIKE '%2%'))))  
 WHEN @day = 3 THEN ((thirdday=@time  and (allocateddays is null or NOT (AllocatedDays LIKE '%3%')))) 
 ELSE AND (1 = 1) 
END

我在第行的 Case 语句中遇到错误 CASE WHEN @day = 1。我的查询出了什么问题。请帮忙。

4

5 回答 5

3

CASE应该重写为一个OR链,每个链都用于它的@day = n一个条件,因为它CASE被期望返回一个值。它不能在WHERE子句中有条件地执行。

如果条件类似@day = 1返回,则它与语句的其余部分一起TRUE用作布尔值。AND这些中的每一个都链接OR到前一个。

where 
 (r.WeekId=@WeekId or @WeekId is null) and
 (ShiftId=@ShiftId or @ShiftId is null)
 and (placeid=@PlaceId or @PlaceId is null)
 and (r.StatusId=3)
 /* I *think* I have the () groups correct here... There's an unnecessary double (()) around firstday|secondday|thirddad */
 AND (
   (@day = 1 AND ((firstday=@time and (allocateddays is null or NOT (AllocatedDays  LIKE '%1%')))))
   OR (@day = 2 AND ((secondday=@time and (allocateddays is null or NOT (AllocatedDays LIKE '%2%')))))
   OR (@day = 3 AND ((thirdday=@time  and (allocateddays is null or NOT (AllocatedDays LIKE '%3%')))))
   /* Not certain if this is necessary in your case, as a catch-all to replace your ELSE */
   OR (@day NOT IN (1,2,3) AND 1=1) 
 )
于 2012-11-30T14:53:10.110 回答
1

WHERE子句中,该CASE语句只能用于指定比较的替代值,如下所示:

where @day = 
    case @SomeCondition
        when 1 then @Sunday
        when 2 then @Monday
        ...
    end
于 2012-11-30T14:57:17.433 回答
1

你不可能ELSE AND...没有编译器来处理这个问题(Fortran 等语言除外)。

于 2012-11-30T15:40:29.833 回答
0

错误的一件事是您在 where 子句中的 CASE 语句正在分配值。例如,当您这样做时firstdaay=@time。你不能那样做。您只能将表达式放在计算为trueor的 where 子句中false,仅此而已。结果,您的整个 where 子句是错误的,坦率地说,对我来说没有多大意义。

条款中的那些条件where似乎更属于select条款:

select ... 
case when @day=1  and (allocateddays is null or NOT (AllocatedDays  LIKE '%1%') then firstday=@time else null end as first_day,
case when @day=2 and (allocateddays is null or NOT (AllocatedDays LIKE '%2%') then secondday=@time else null end as second_day

from ... 
于 2012-11-30T14:55:11.287 回答
0

这行:ELSE AND (1 = 1) 看起来非常可疑。拿出来试试。

于 2012-11-30T15:00:01.050 回答