使用列来评估另一列oracle

时间:2013-03-12 20:55:14

标签: sql oracle math

我有一个包含3个字段的表:

字段1(NUMBER):具有如下值:1,2,50,40

字段2(VARCHAR):具有以下值:“+”,“ - ”,“*”

字段3(NUMBER):类似Field1:5,65.4,90

我如何评估这个领域的内容2。

示例

|field1| field2| field3| RESULT
-------------------------------
|     1|      +|      5|  6
|     1|      *|      5|  5
|     1|      -|      5| -4

4 个答案:

答案 0 :(得分:2)

我不知道PL / SQL中EXECUTE IMMEDIATE之外的任何EVAL类型功能,并且一次只限于一个语句。你不能构建一个可以为一行添加的东西,为另一行添加,然后减去另一行,但你可以创建一个游标,遍历它,并构建一个EXECUTE IMMEDIATE来评估每个游标上的值行。如果您认为操作比使用两个操作数的简单数学更复杂,那么一定要考虑一下。

下面的查询将按照你的要求进行,但是如果你想做的事情比两列之间的操作更复杂,那么很快就会变得很麻烦:

SELECT
  CASE field2
    WHEN '+' THEN field1 + field3
    WHEN '*' THEN field1 * field3
    WHEN '-' THEN field1 - field3
  END
FROM ...

答案 1 :(得分:2)

正如Annjawn在this answer中解释的那样,您可以使用XMLQuery的一些内置功能,特别是.getnumberval()来伪造公式。这将比CASE声明慢得多,但它更清晰。

假设表:

create table tmp_test (
   field1 number not null
 , field2 varchar2(1) not null
 , field3 number not null );

insert all
  into tmp_test values (1, '+', 5)
  into tmp_test values (1, '*', 5)
  into tmp_test values (1, '-', 5)
select * from dual;

您的查询将如下所示:

SQL> select xmlquery(field1 || field2 || field3 returning content
  2                   ).getnumberval() as field4
  3    from tmp_test;

    FIELD4
----------
         6
         5
        -4

SQL Fiddle

我会强烈建议不要在数据库中存储计算列。它只会导致问题,就像更新数据库一样,列不会更新。正确的方法是拥有一个视图,其中包含计算的定义,并始终从此视图中选择或使用VIRTUAL column中定义的create table documentation

然后,您可以使用XMLQueryDETERMINISTIC function(例如the one provided by APC)自动计算您的列。

如果您的表创建如下:

create table tmp_test (
   field1 number not null
 , field2 varchar2(1) not null
 , field3 number not null
 , field4 number generated always as (
           xmlquery(field1 || field2 || field3 returning content
                 ).getnumberval()
           ) virtual
    );

然后一个更简单的查询将得到你的结果

SQL> select * from tmp_test;

    FIELD1 F     FIELD3     FIELD4
---------- - ---------- ----------
         1 +          5          6
         1 *          5          5
         1 -          5         -4

SQL Fiddle

这样做的另一个好处是,您的计算始终以完全相同的方式完成。对于需要此计算列

的每个代码,它们的实现方式不同

答案 2 :(得分:1)

您可以构建评估函数

create or replace function eval 
   ( n1 in number
     , n2 in number
     , op in varchar2 )
return number deterministic
as
   result number;
begin
   execute immediate ' select :1 '|| op || ' : 2 from dual'
      into result
      using n1, n2;
    return result;
end;
/

然后您可以在SELECT语句中调用它:

select eval ( field1, field3, field2) as result 
from your_table;

这将处理简单的算术,但对于更复杂的公式来说,这不是一个好方法。如果你想沿着那条路走下去,我建议你按照我在PL / SQL中做数学的另一个问题的回答中的链接。 Find out more

答案 3 :(得分:0)

SELECT
  field1,
  field2,
  field3,
  Case
   When field2='+' then field1+field3
   When field2='*' then field1*field3
   When field2='-' then field3-field1
   else 0
  end as Result
FROM table

http://www.techonthenet.com/oracle/functions/case.php