我有一个表格tab_1,其中包含以下值。
ID Calculation value
1 10
2 10
3 1+2
4 5
5 3-2
6 5+1
需要帮助编写以下逻辑的查询。我有一个表,其中记录包含计算字符串或计算中使用的值。我需要像这样解析calculation
:
ID 3 is the sum of ID 1 and 2.
ID 5 is the minus of ID 3 and 2.
ID 6 is the sum of ID 5 and 1.
然后我需要为引用的ID选择记录并执行计算。我的 预期产出:
ID Calculation value
3 1+2 20
5 3-2 10
6 5+1 20
谢谢 - 纳尼
答案 0 :(得分:3)
"需要帮助编写以下逻辑的查询。"
这不是可以在纯SQL中解决的问题,因为:
这是一个递归函数,可以产生您期望的答案。它有三个私有过程,因此函数的主体很容易理解。在伪代码中:
value
,则返回并退出calculation
calculation
的每个部分递归1,3,4,直至2 需要滚动的道歉:
create or replace function dyn_calc
(p_id in number)
return number
is
result number;
n1 number;
n2 number;
l_rec t23%rowtype;
l_val number;
type split_calc_r is record (
val1 number
, operator varchar2(1)
, val2 number
);
l_calc_rec split_calc_r;
function get_rec
(p_id in number)
return t23%rowtype
is
rv t23%rowtype;
begin
select *
into rv
from t23
where id = p_id;
return rv;
end get_rec;
procedure split_calc
(p_calc in varchar2
, p_n1 out number
, p_n2 out number
, p_operator out varchar2)
is
begin
p_n1 := regexp_substr(p_calc, '[0-9]+', 1, 1);
p_n2 := regexp_substr(p_calc, '[0-9]+', 1, 2);
p_operator := translate(p_calc, '-+*%01923456789','-+*%'); --regexp_substr(p_calc, '[\-\+\*\%]', 1, 1);
end split_calc;
function exec_calc
(p_n1 in number
, p_n2 in number
, p_operator in varchar2)
return number
is
rv number;
begin
execute immediate
'select :n1 ' || p_operator || ' :n2 from dual'
into rv
using p_n1, p_n2;
return rv;
end exec_calc;
begin
l_rec := get_rec(p_id);
if l_rec.value is not null then
result := l_rec.value;
else
split_calc(l_rec.calculation
, l_calc_rec.val1
, l_calc_rec.val2
, l_calc_rec.operator);
n1 := dyn_calc (l_calc_rec.val1);
n2 := dyn_calc (l_calc_rec.val2);
result := exec_calc(n1, n2, l_calc_rec.operator);
end if;
return result;
end;
/
像这样跑:
SQL> select dyn_calc(6) from dual;
DYN_CALC(6)
-----------
20
SQL>
或者,要完全按照您的要求获得输出:
select id, calculation, dyn_calc(id) as value
from t23
where calculation is not null;
备注强>
split_calc()
proc使用translate()
来提取运算符而不是正则表达式。这是因为regexp_substr(p_calc, '[\-\+\*\%]', 1, 1)
神秘地吞噬了-
。这似乎是一个与环境有关的错误。因此,将此功能扩展到流程1+4+2
将会很尴尬。 答案 1 :(得分:1)
在SQL中:
select 'ID ' +ID+ ' is the ' + case when calculation like '%-%' then ' minus '
when calculation like '%+%' then ' sum ' END +' of
ID'+replace(replace(calculation,'+',' and '),'-',' and ')
from tab_1
where calculation is not null
在Oracle中:
select 'ID ' ||ID|| ' is the ' || case when calculation like '%-%' then ' minus '
when calculation like '%+%' then ' sum ' END|| ' of
ID'||replace(replace(calculation,'+',' and '),'-',' and ')
from tab_1
where calculation is not null