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