SQL - 过滤器中的 CASE 语句,可选择使用
SQL - CASE statement in filter with optional use
抱歉,我没有更好的词来标题我的问题,但本质上我正在寻找 CASE/AND...OR 过滤条件中的语句的实现,其中如果特定 ID 的值不是NULL 且大于 0,则仅考虑该 ID 的条件,否则根本不需要使用该 ID 的条件。
示例 1:
select emp_id, cust_id, date_id
from employee a
join customer l
on a.id = l.id
join time_table ACT
on a.join_date_id = ACT.date_id
where a.emp_id = 1
and l.cust_id in (2, 3)
and ACT.date_id >= to_char((sysdate - EXTRACT(DAY FROM (SYSDATE))) - 90, 'DD-MON-YYYY')
and ACT.date_id <= to_char(sysdate - EXTRACT(DAY FROM (SYSDATE)), 'DD-MON-YYYY')
and a.sub_emp_id = CASE WHEN @sub_emp_id IS NOT NULL AND @sub_emp_id > 0 THEN @sub_emp_id WHEN @sub_emp_id IS NULL THEN @sub_emp_id ELSE @sub_emp_id END -- where condition is, if sub_emp_id is not null and if sub_emp_id > 0 then use the value of sub_emp_id otherwise if sub_emp_id is NULL, then don't use the condition for sub_emp_id altogether.
示例 2 -
select emp_id, cust_id, date_id
from employee a
join customer l
on a.id = l.id
join time_table ACT
on a.join_date_id = ACT.date_id
where (a.emp_id = 1
and l.cust_id in (2, 3)
and ACT.date_id >= to_char((sysdate - EXTRACT(DAY FROM (SYSDATE))) - 90, 'DD-MON-YYYY')
and ACT.date_id <= to_char(sysdate - EXTRACT(DAY FROM (SYSDATE)), 'DD-MON-YYYY')
and a.sub_emp_id > 0)
OR
(a.emp_id = 1
and l.cust_id in (2, 3)
and ACT.date_id >= to_char((sysdate - EXTRACT(DAY FROM (SYSDATE))) - 90, 'DD-MON-YYYY')
and ACT.date_id <= to_char(sysdate - EXTRACT(DAY FROM (SYSDATE)), 'DD-MON-YYYY')) -- where condition is, "if sub_emp_id is not null and if sub_emp_id > 0" then use the value of sub_emp_id otherwise "if sub_emp_id is NULL, then don't use the condition for sub_emp_id altogether".
如果我理解正确的话,你会希望 sub_emp_id
上的过滤器看起来像这样:
...
and (@sub_emp_id is null or
@sub_emp_id <= 0 or
a.sub_temp_id = @sub_emp_id)
通常您需要对 "all" 进行空匹配。简单的模式是这样的:
WHERE coalesce(@sub_emp_id, a.sub_temp_id) = a.sub_temp_id
我认为你是为此拍摄的:
case
when @sub_emp_id > 0 /* not null is also implied */
then case when a.sub_emp_id = @sub_emp_id then 1 else 0 end
else 1
end = 1
我认为这些是等价的选择:
not (@sub_emp_id > 0 and a.sub_emp_id <> @sub_emp_id)
coalesce(@sub_emp_id, 0) <= 0 or a.sub_emp_id = @sub_emp_id
抱歉,我没有更好的词来标题我的问题,但本质上我正在寻找 CASE/AND...OR 过滤条件中的语句的实现,其中如果特定 ID 的值不是NULL 且大于 0,则仅考虑该 ID 的条件,否则根本不需要使用该 ID 的条件。
示例 1:
select emp_id, cust_id, date_id
from employee a
join customer l
on a.id = l.id
join time_table ACT
on a.join_date_id = ACT.date_id
where a.emp_id = 1
and l.cust_id in (2, 3)
and ACT.date_id >= to_char((sysdate - EXTRACT(DAY FROM (SYSDATE))) - 90, 'DD-MON-YYYY')
and ACT.date_id <= to_char(sysdate - EXTRACT(DAY FROM (SYSDATE)), 'DD-MON-YYYY')
and a.sub_emp_id = CASE WHEN @sub_emp_id IS NOT NULL AND @sub_emp_id > 0 THEN @sub_emp_id WHEN @sub_emp_id IS NULL THEN @sub_emp_id ELSE @sub_emp_id END -- where condition is, if sub_emp_id is not null and if sub_emp_id > 0 then use the value of sub_emp_id otherwise if sub_emp_id is NULL, then don't use the condition for sub_emp_id altogether.
示例 2 -
select emp_id, cust_id, date_id
from employee a
join customer l
on a.id = l.id
join time_table ACT
on a.join_date_id = ACT.date_id
where (a.emp_id = 1
and l.cust_id in (2, 3)
and ACT.date_id >= to_char((sysdate - EXTRACT(DAY FROM (SYSDATE))) - 90, 'DD-MON-YYYY')
and ACT.date_id <= to_char(sysdate - EXTRACT(DAY FROM (SYSDATE)), 'DD-MON-YYYY')
and a.sub_emp_id > 0)
OR
(a.emp_id = 1
and l.cust_id in (2, 3)
and ACT.date_id >= to_char((sysdate - EXTRACT(DAY FROM (SYSDATE))) - 90, 'DD-MON-YYYY')
and ACT.date_id <= to_char(sysdate - EXTRACT(DAY FROM (SYSDATE)), 'DD-MON-YYYY')) -- where condition is, "if sub_emp_id is not null and if sub_emp_id > 0" then use the value of sub_emp_id otherwise "if sub_emp_id is NULL, then don't use the condition for sub_emp_id altogether".
如果我理解正确的话,你会希望 sub_emp_id
上的过滤器看起来像这样:
...
and (@sub_emp_id is null or
@sub_emp_id <= 0 or
a.sub_temp_id = @sub_emp_id)
通常您需要对 "all" 进行空匹配。简单的模式是这样的:
WHERE coalesce(@sub_emp_id, a.sub_temp_id) = a.sub_temp_id
我认为你是为此拍摄的:
case
when @sub_emp_id > 0 /* not null is also implied */
then case when a.sub_emp_id = @sub_emp_id then 1 else 0 end
else 1
end = 1
我认为这些是等价的选择:
not (@sub_emp_id > 0 and a.sub_emp_id <> @sub_emp_id)
coalesce(@sub_emp_id, 0) <= 0 or a.sub_emp_id = @sub_emp_id