【问题标题】:Is it possible to check whether a value is in the list of items in a single Oracle Decode Function?是否可以检查一个值是否在单个 Oracle 解码函数的项目列表中?
【发布时间】:2012-02-22 05:46:39
【问题描述】:

我想知道是否可以将值与解码函数中的项目列表进行比较。基本上我想知道是否可以将解码语句的 'search' 值设为一个列表。例如,

decode(task_id, (1,2,3), 3 * task_time) 

虽然这段代码不会编译。那么这是这种情况的唯一选择(不使用case-when)还是有其他方法可以做到这一点?

decode(task_id, 1, 3 * task_time,
                2, 3 * task_time,
                3, 3 * task_time)

我正在使用 Oracle 10gR2。非常感谢任何帮助。

【问题讨论】:

  • 虽然我理解你不愿意使用case 声明 - 我不认为它们看起来很干净 - 它们比解码功能强大得多,可以在更多地方使用,并且可以跨 RDBMS 转移. @Codo 的答案就是您需要的答案。
  • 棘手的问题。但是为什么你不使用 CASE?解码对你有好处吗?
  • 这个问题只是我个人兴趣的结果。此外,我想在用大数据填充相关表后测试解码函数与 case 子句。
  • 您使用的是 Oracle 10g。为什么要尝试让 DECODE() 做一些它不能做的事情,而不是使用可以做的 CASE()?
  • 好的。大多数答案和 cmets 证明,在我的案例中使用 case 子句是理想的解决方案。所以,我将在这里接受@Codo 的回答。谢谢大家的回复。

标签: oracle decode


【解决方案1】:

如果单个值列表就足够了,您可以将其转换为CASEIN 子句:

case when task_id in (1, 2, 3) then 3 * task_time else null end

【讨论】:

  • 就像我在问题中所说的那样,我想知道是否可以在不使用 case-when 子句的情况下使用解码功能。
【解决方案2】:

我认为不可能以这种方式使用带解码的列表。根据文档:

DECODE 将 expr 与每个搜索值一一进行比较。如果 expr 相等 进行搜索,然后 Oracle 数据库返回相应的结果。如果 未找到匹配项,则 Oracle 返回默认值

所以task_id与一个搜索值一一比较。如果搜索值是一个列表,则无法与单个值进行比较。

【讨论】:

    【解决方案3】:

    我找到了解决办法:)

    select 
        decode(
              task_id, 
              (select task_id from dual where task_id in (1,2,3)), 
              3*task_time) 
    

    【讨论】:

    • decode(task_id,decode(task_id,1,task_id,2,task_id,3,task_id),3*task_time)
    【解决方案4】:

    decode ( (taskid-1)*(taskid-2)*(taskid-3), 0, 3 * tasktime ) 可以做你想做的事

    这是一个工作示例:

    with a as (
      select 1 taskid, 11 tasktime from dual union all
      select 2 taskid, 11 tasktime from dual union all
      select 3 taskid, 11 tasktime from dual union all
      select 4 taskid, 11 tasktime from dual
    )
    select 
      taskid,
      decode (
        (taskid-1) *
        (taskid-2) *
        (taskid-3) ,
        0, 3 * tasktime 
    )                                  decoded
    from a;
    

    【讨论】:

    • 非常聪明,但这是在 Oracle7 时代所必需的解决方法。 OP 在 Oracle 10g 上,应该只使用 CASE()。
    【解决方案5】:

    你可以使用 union all:

    select 3 * task_time from your_table where task_id in (1,2,3)
    union all
    select task_time from your_table where task_id not in (1,2,3)
    

    但是为什么?

    【讨论】:

      【解决方案6】:

      如果条件:

      IF vVal in (3,1,2) THEN
           dbms_output.put_line('FOUND');
         ELSE
          dbms_output.put_line('NOT FOUND');
         END IF;
      

      【讨论】:

        【解决方案7】:

        我已经看到instr(...) 和静态字符串被用作快速确定一个值是否是您正在寻找的多个值之一作为返回值的条件。您可能需要选择一个分隔符,但对于有限的数据集,您甚至可以省略它。它避免使用 case-when、子查询和 PL/SQL。据我所知,没有更短的方法可以做到这一点:

        decode(instr('123', taskid), 0, null, taskid * 3)
        

        当你想设置异常时也非常方便(例如返回taskid,如果它等于1,则不进行乘法运算):

        decode(instr('12345', taskid), 0, null, 1, taskid, taskid * 3)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-07-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-31
          • 1970-01-01
          • 2015-09-14
          相关资源
          最近更新 更多