在 where 子句中使用 case 语句
using case statement in a where clause
您好,由于我的代码错误,我遗漏了一些东西。
select * from ##ScheduleDetail SD
left join ##HolidayFilterTbl HF on SD.Scheduledate = HF.Testdate
where (ScheduleDate = testdate)
and
(Case
when HF.IsHoliday = 1 then (overtime = 1 and makeup = 0)
else
(overtime = 0 and Makeup = 0)
end
)
and
DOW = 5
order by ActivityStartTime
我尝试了多种组合,但每一种组合都在第一个等号或第二个等号处出错。我错过了什么?
case
表达式的分支只能 return 值,不能在 where
条件下计算其他表达式。但是,您可以使用 and
和 or
逻辑运算符模拟此行为:
select *
from ##ScheduleDetail SD
left join ##HolidayFilterTbl HF on SD.Scheduledate = HF.Testdate
where (ScheduleDate = testdate) and
((HF.IsHoliday = 1 and overtime = 1 and makeup = 0) or
(overtime = 0 and Makeup = 0)) and
DOW = 5
order by ActivityStartTime
请注意,问题中 case
表达式的两个分支(或答案中 or
的两侧)都有 makeup = 0
,因此您可以将其提取出来它并稍微简化条件:
select *
from ##ScheduleDetail SD
left join ##HolidayFilterTbl HF on SD.Scheduledate = HF.Testdate
where ScheduleDate = testdate and
makeup = 0 and
((HF.IsHoliday = 1 and overtime = 1) or
overtime = 0) and
DOW = 5
order by ActivityStartTime
如果您仍然想知道如何在 WHERE 子句中使用 CASE 语句 表达式,则必须将 CASE 表达式与一个值进行比较,因为这是对条件理解的语法包含在 WHERE 子句中。请参阅下面的模拟示例。
SELECT *
FROM ##ScheduleDetail SD
LEFT JOIN ##HolidayFilterTbl HF ON SD.Scheduledate = HF.Testdate
WHERE(ScheduleDate = testdate)
AND
/* If you wish to stick with using a CASE Expression within the WHERE Clause set the the CASE Expression equal to 'something'. I usually stick with 1 or 0 'true/false'.
| You simply have to create your own True/False evaluation. You can add your logic checks within a CASE Expression within
| the WHERE Clause and when your logic is TRUE THEN return 1. Basically you are saying when 1 = 1 then return Record.
*/
1 =
Case
WHEN HF.IsHoliday = 1 AND makeup = 0 THEN
CASE WHEN (overtime = 1 OR overtime = 0) THEN 1 END /* Return 1 here to evaluation to TRUE */
ELSE
0 /* You can add another CASE here if needed and when the condition you write in evaluations to 1 'true' return record */
END
AND
DOW = 5
ORDER BY ActivityStartTime;
我在 WHERE 子句中使用 CASE 表达式而不是 AND/ORs 有几个原因。一个次要的原因是它允许我在 CASE 表达式内的 WHERE 子句中包含和组织逻辑,而不是将多个 AND/ORs 全部嵌套在一起。我还发现,在遇到接受变量的动态查询时,在 WHERE 子句中使用 CASE 表达式很有用,这些变量稍后将插入到 SQL 中,然后再发送到数据库进行处理。在使用 Dynamic SQL 的情况下,有时必须使用 CASE 语句,因为在 WHERE 子句中可能存在被比较的数据不是 column.field 值,而是与用户选择或状态(例如)进行比较的硬编码值...它可能是通过应用程序传入的静态值,这就是我支持的 Web 应用程序的工作方式,这就是我提出它的原因。
基本上,了解如何在 WHERE 子句中使用 CASE 表达式是件好事,因为在某些情况下,评估某些数据的唯一方法是使用 CASE 表达式。
我没有数据可以对此进行测试,这不是重点。我的回答的重点是简单地为您提供现有答案的替代方案。在我看来,这个逻辑是基本的,已经提供的答案是正确的,但我的答案是为了演示如何在 WHERE 子句中使用 CASE。
如果有兴趣,请参阅 this SO Post 以了解 CASE 语句与 CASE 表达式之间的区别,但要知道该术语在数据库之间略有不同。
举个例子... SQL 服务器将它们称为 Simple vs Searched 但将它们全部称为 CASE 表达式。因此,CASE 表达式可以是简单的或搜索的 CASE,可以在语句中使用。
您好,由于我的代码错误,我遗漏了一些东西。
select * from ##ScheduleDetail SD
left join ##HolidayFilterTbl HF on SD.Scheduledate = HF.Testdate
where (ScheduleDate = testdate)
and
(Case
when HF.IsHoliday = 1 then (overtime = 1 and makeup = 0)
else
(overtime = 0 and Makeup = 0)
end
)
and
DOW = 5
order by ActivityStartTime
我尝试了多种组合,但每一种组合都在第一个等号或第二个等号处出错。我错过了什么?
case
表达式的分支只能 return 值,不能在 where
条件下计算其他表达式。但是,您可以使用 and
和 or
逻辑运算符模拟此行为:
select *
from ##ScheduleDetail SD
left join ##HolidayFilterTbl HF on SD.Scheduledate = HF.Testdate
where (ScheduleDate = testdate) and
((HF.IsHoliday = 1 and overtime = 1 and makeup = 0) or
(overtime = 0 and Makeup = 0)) and
DOW = 5
order by ActivityStartTime
请注意,问题中 case
表达式的两个分支(或答案中 or
的两侧)都有 makeup = 0
,因此您可以将其提取出来它并稍微简化条件:
select *
from ##ScheduleDetail SD
left join ##HolidayFilterTbl HF on SD.Scheduledate = HF.Testdate
where ScheduleDate = testdate and
makeup = 0 and
((HF.IsHoliday = 1 and overtime = 1) or
overtime = 0) and
DOW = 5
order by ActivityStartTime
如果您仍然想知道如何在 WHERE 子句中使用 CASE 语句 表达式,则必须将 CASE 表达式与一个值进行比较,因为这是对条件理解的语法包含在 WHERE 子句中。请参阅下面的模拟示例。
SELECT *
FROM ##ScheduleDetail SD
LEFT JOIN ##HolidayFilterTbl HF ON SD.Scheduledate = HF.Testdate
WHERE(ScheduleDate = testdate)
AND
/* If you wish to stick with using a CASE Expression within the WHERE Clause set the the CASE Expression equal to 'something'. I usually stick with 1 or 0 'true/false'.
| You simply have to create your own True/False evaluation. You can add your logic checks within a CASE Expression within
| the WHERE Clause and when your logic is TRUE THEN return 1. Basically you are saying when 1 = 1 then return Record.
*/
1 =
Case
WHEN HF.IsHoliday = 1 AND makeup = 0 THEN
CASE WHEN (overtime = 1 OR overtime = 0) THEN 1 END /* Return 1 here to evaluation to TRUE */
ELSE
0 /* You can add another CASE here if needed and when the condition you write in evaluations to 1 'true' return record */
END
AND
DOW = 5
ORDER BY ActivityStartTime;
我在 WHERE 子句中使用 CASE 表达式而不是 AND/ORs 有几个原因。一个次要的原因是它允许我在 CASE 表达式内的 WHERE 子句中包含和组织逻辑,而不是将多个 AND/ORs 全部嵌套在一起。我还发现,在遇到接受变量的动态查询时,在 WHERE 子句中使用 CASE 表达式很有用,这些变量稍后将插入到 SQL 中,然后再发送到数据库进行处理。在使用 Dynamic SQL 的情况下,有时必须使用 CASE 语句,因为在 WHERE 子句中可能存在被比较的数据不是 column.field 值,而是与用户选择或状态(例如)进行比较的硬编码值...它可能是通过应用程序传入的静态值,这就是我支持的 Web 应用程序的工作方式,这就是我提出它的原因。
基本上,了解如何在 WHERE 子句中使用 CASE 表达式是件好事,因为在某些情况下,评估某些数据的唯一方法是使用 CASE 表达式。
我没有数据可以对此进行测试,这不是重点。我的回答的重点是简单地为您提供现有答案的替代方案。在我看来,这个逻辑是基本的,已经提供的答案是正确的,但我的答案是为了演示如何在 WHERE 子句中使用 CASE。
如果有兴趣,请参阅 this SO Post 以了解 CASE 语句与 CASE 表达式之间的区别,但要知道该术语在数据库之间略有不同。
举个例子... SQL 服务器将它们称为 Simple vs Searched 但将它们全部称为 CASE 表达式。因此,CASE 表达式可以是简单的或搜索的 CASE,可以在语句中使用。