【问题标题】:SQL QUERY WITH A CASE IN WHERE CLAUSE在 WHERE 子句中带有 case 的 SQL 查询
【发布时间】:2022-01-06 21:34:58
【问题描述】:

我想编写一个查询 - 以涵盖一个案例:- 我想检查 code_id(输入变量)是否存在任何杂项值,如果没有,则使用 code_id 作为默认值(即 OTH)。

类似

select MISC_FLAGS  
from systemcode 
where rec_type = 'C' 
   and code_type = 'SAN' 
   and  CODE_ID = 'HT';

如果没有这个值,那么它应该返回结果:

select MISC_FLAGS  
from systemcode 
where rec_type = 'C' 
   and code_type = 'SAN' 
   and  CODE_ID = 'OTH';

【问题讨论】:

  • 请提供样本数据和该样本数据所需的输出。

标签: sql oracle oracle11g


【解决方案1】:

你可以使用这个查询

select MISC_FLAGS  from systemcode where rec_type = 'C' and code_type = 'SAN' and CODE_ID = 'HT' or (
CODE_ID = 'OTH' and TABLE_ID not in (select TABLE_ID   from systemcode where rec_type = 'C' and code_type = 'SAN' and CODE_ID = 'HT') 
)

【讨论】:

  • 非常感谢 arlabbafi。我得到了上下文。我很快尝试了解决方案,但无法运行它,因为它给我一个错误 - table_id 不是有效的标识符,如果我试图用表的另一个标识符替换它,它会给我两个输入变量的值(HT 和 OTH)... 因为只有当 HT 不存在时我才需要 OTH 值
  • 您应该将 TABLE_ID 替换为表的主键名称
【解决方案2】:

这可能是一种选择;在代码中读取 cmets。

当我在 SQL*Plus 中运行它时,我使用了替换变量;根据您的操作方式,它可能是一个绑定变量 (:par_code_id);或者,如果它是一个过程/函数,您只需使用 par_code_id

SQL> with systemcode (misc_flags, rec_type, code_type, code_id) as
  2    -- sample data
  3    (select 'MSC', 'C', 'SAN', 'OTH' from dual union all
  4     select 'ABC', 'C', 'SAN', 'TT'  from dual
  5    ),
  6  temp as
  7    -- MX = 1 if :PAR_CODE_ID exists in SYSTEMCODE table
  8    -- MX = 0 if :PAR_CODE_ID does not exist in SYSTEMCODE table
  9    (select nvl(max(1), 0) mx
 10     from systemcode
 11     where exists (select null from systemcode
 12                   where code_id = '&&par_code_id'
 13                  )
 14     )
 15  select s.misc_flags
 16  from systemcode s cross join temp t
 17  where s.rec_type = 'C'
 18    and s.code_type = 'SAN'
 19    -- depending on MX value, select either row(s) that match :PAR_CODE_ID or 'OTH'
 20    and s.code_id = case when t.mx = 1 then '&&par_code_id'
 21                         else 'OTH'
 22                    end;
Enter value for par_code_id: HT          --> doesn't exist, so use OTH

MIS
---
MSC

SQL> undefine par_code_id
SQL> /
Enter value for par_code_id: TT         --> it exists

MIS
---
ABC

【讨论】:

    【解决方案3】:

    您可以使用条件聚合在不同列中选择您输入的OTHCODE_ID。然后根据指定CODE_ID的存在选择其中一列。

    create table systemcode (
      MISC_FLAGS,
      rec_type,
      code_type,
      CODE_ID
    ) as
    select 'HT', 'C', 'SAN', 'HT' from dual union all
    select 'OTH', 'C', 'SAN', 'OTH' from dual
    
    select decode(
      /*If the specified code is present*/
      max(decode(code_id, 'HT', code_id)),
      'HT',
      /*then select a value for that code*/
      max(decode(code_id, 'HT', MISC_FLAGS)),
      /*else - select default value*/
      max(decode(code_id, 'OTH', MISC_FLAGS))
    ) as code_id
    from systemcode
    where code_id in ('HT', 'OTH')
    
    | CODE_ID | | :-------- | |高温 |
    select decode(
      max(decode(code_id, 'AAA', code_id)),
      'AAA',
      max(decode(code_id, 'AAA', MISC_FLAGS)),
      max(decode(code_id, 'OTH', MISC_FLAGS))
    ) as code_id
    from systemcode
    where code_id in ('AAA', 'OTH')
    
    | CODE_ID | | :-------- | |其他 |

    db小提琴here

    【讨论】:

      【解决方案4】:

      如果每个代码只有一行要返回,您可以使用:

      SELECT misc_flags
      FROM   (
        SELECT misc_flags 
        FROM   systemcode 
        WHERE  rec_type  = 'C' 
        AND    code_type = 'SAN' 
        AND    code_id   IN ('HT', 'OTH')
        ORDER BY code_id ASC
      )
      WHERE  ROWNUM = 1;
      

      如果可以有多行:

      SELECT misc_flags
      FROM   (
        SELECT misc_flags,
               RANK() OVER (ORDER BY code_id ASC) AS rnk
        FROM   systemcode 
        WHERE  rec_type  = 'C' 
        AND    code_type = 'SAN' 
        AND    code_id   IN ('HT', 'OTH')
      )
      WHERE  rnk = 1;
      

      【讨论】:

      • order by nullif(code_id, 'OTH') nulls last 将更加灵活,因为它并不意味着输入代码在“之前”OTH(例如,ZZZ
      • @astentx WHERE 上的 code_id 过滤器消除了对类似内容的需求。
      • 很抱歉,仍然无法理解。 db<>fiddle.
      • @astentx 您已更改问题的要求。在这种情况下,请在排序中使用DESC 而不是ASC
      • OP 中的要求:“想要检查 code_id(输入变量)是否存在任何杂项值”
      猜你喜欢
      • 2014-10-13
      • 1970-01-01
      • 2018-09-13
      • 2016-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多