Oracle中where子句中的case表达式
Posted
技术标签:
【中文标题】Oracle中where子句中的case表达式【英文标题】:Case expression in where clause in Oracle 【发布时间】:2018-09-12 05:30:49 【问题描述】:我根据某些条件从 Oracle 表中提取了一些数据。
如果 JobFunctionCode = 'ADMIN' 的人在他辞职时会填充 notify_termination_date,然后他的数据就会被提取。
来自其他 JobFunctionCode 的人(如经理、财务等)在他们辞职时填充了接受的终止日期,然后他们的数据应该被提取。
因此,根据这些条件提取数据,我在WHERE
子句中编写了一个案例语句,但它给出了缺少括号的错误。此 SQL 是计划运行,因此我已将终止日期设置为 sysdate
,它将每天运行。
select ppos.person_id, paam.position_id, pjf.job_function_code
from
per_all_assignments_m paam, per_periods_of_service ppos, per_jobs_f pjf
where
case
when pjf.job_function_code = 'ADMIN' then (TO_CHAR(ppos.notified_termination_date, 'YYYY-MM-DD') = TO_CHAR(SYSDATE, 'YYYY-MM-DD'))
else (TO_CHAR(ppos.accepted_termination_date, 'YYYY-MM-DD') = TO_CHAR(SYSDATE, 'YYYY-MM-DD'))
end
and paam.person_id = ppos.person_id
and paam.job_id = pjf.job_id
and paam.primary_flag = 'Y'
and TO_CHAR(paam.effective_end_date, 'YYYY-MM-DD') = '4712-12-31'
and TO_CHAR(pjf.effective_end_date, 'YYYY-MM-DD') = '4712-12-31'
另外,当两个 JobFunctionCode 中的 Person 终止时,可能会出现两个 person 数据都应该被拉出的情况,所以我认为在这种情况下不能使用 CASE
表达式。
请告诉我这里的逻辑怎么写?
【问题讨论】:
所以,如果管理员在 notify_termination_date 辞职而其他 jobFunctionCode 在接受的termination_date 辞职,基本上你需要获取数据。有要求吗? 是的,而且如果 JobFunctionCode 'ADMIN' 的人 A 和 JobFunctionCode 'MANAGER' 的人 B 在同一天辞职,那么这两个人的数据都应该来,某种 OR 逻辑..可能是.. 【参考方案1】:where 子句应该是:
where
(
(pjf.job_function_code = 'ADMIN' and TO_CHAR(ppos.notified_termination_date, 'YYYY-MM-DD') = TO_CHAR(SYSDATE, 'YYYY-MM-DD'))
or (pjf.job_function_code <> 'ADMIN' and TO_CHAR(ppos.accepted_termination_date, 'YYYY-MM-DD') = TO_CHAR(SYSDATE, 'YYYY-MM-DD'))
)
and <rest of clauses>
我还没有查看其余部分,是否需要 TO-CHAR 等,但这将修复您的 where 子句。
【讨论】:
【参考方案2】:你可以试试:
((case
when pjf.job_function_code = 'ADMIN'
case
when (TO_CHAR(ppos.notified_termination_date, 'YYYY-MM-DD') = TO_CHAR(SYSDATE, 'YYYY-MM-DD')) then 'Y'
else 'N'
end
else
case
when (TO_CHAR(ppos.accepted_termination_date, 'YYYY-MM-DD') = TO_CHAR(SYSDATE, 'YYYY-MM-DD')) then 'Y'
else 'N'
end
end )='Y'
or exists (select * from <<tablename>> pjf.job_function_code = 'ADMIN'
and (TO_CHAR(ppos.notified_termination_date, 'YYYY-MM-DD')) = (TO_CHAR(ppos.accepted_termination_date, 'YYYY-MM-DD'))));
P.S: 只需检查括号闭包,并根据您的表设计将查询写入存在子句中
【讨论】:
【参考方案3】:在where
子句不允许的情况下,您可以在下面写下您的条件
where
( pjf.job_function_code = 'ADMIN' AND
(TO_CHAR(ppos.notified_termination_date, 'YYYY-MM-DD') = TO_CHAR(SYSDATE, 'YYYY-MM-DD'))
Or (TO_CHAR(ppos.accepted_termination_date, 'YYYY-MM-DD') = TO_CHAR(SYSDATE, 'YYYY-MM-DD'))
)
and paam.person_id = ppos.person_id
and paam.job_id = pjf.job_id
and paam.primary_flag = 'Y'
and TO_CHAR(paam.effective_end_date, 'YYYY-MM-DD') = '4712-12-31'
and TO_CHAR(pjf.effective_end_date, 'YYYY-MM-DD') = '4712-12-31'
【讨论】:
以上是关于Oracle中where子句中的case表达式的主要内容,如果未能解决你的问题,请参考以下文章
WHERE子句中的SQL Server CASE表达式以检查NULL值