现在有这样一个功能,可是没有思路,各位帮忙看下。
有张表假设只有一列,字段都是number型的,现在是知道最后的和是一个数,我想知道这个数都是哪几个字段求和出来的。
比如100,表中有几十个字段,其中这几个字段相加得100,现在找出是哪几个字段的和是100,
不知道我说的明白不明白,谢谢各位了。ps.可能第一字段+第三字段+第N字段=100 或第5字段=100 或第四字段+第五字段=100
谢谢了啊
有张表假设只有一列,字段都是number型的,现在是知道最后的和是一个数,我想知道这个数都是哪几个字段求和出来的。
比如100,表中有几十个字段,其中这几个字段相加得100,现在找出是哪几个字段的和是100,
不知道我说的明白不明白,谢谢各位了。ps.可能第一字段+第三字段+第N字段=100 或第5字段=100 或第四字段+第五字段=100
谢谢了啊
declare
sum_target integer := 10; --和为10
num_limit integer := 9; --可用的数字为1-9
type arr is table of integer index by binary_integer;
result_arr arr; --存放符合条件的数值的数值
tmp_int integer; --存放准备插入数组的数字
sum_current integer := 0; --当前数组中数值的和
--用来操作数组的存储过程,add_int:传入的数值;
--add_type: 0:将add_int替换最后一个节点;1:添加到新的节点;-1:删除最后一个节点
procedure proc(add_int in integer, add_type in integer) is
begin
if add_type = 0 then
sum_current := sum_current - result_arr(result_arr.last) + add_int;
result_arr(result_arr.last) := add_int;
elsif add_type = 1 then
-- i:=i+1;
sum_current := sum_current + add_int;
result_arr(nvl(result_arr.last, 0) + 1) := add_int;
elsif add_type = -1 then
sum_current := sum_current - result_arr(result_arr.last);
result_arr.delete(result_arr.last);
-- i:=i-1;
end if;
end proc;
--打印结果
procedure print_res as
result_str varchar2(32767); --存放要打印的结果字符串
begin
result_str := null;
for x in 1 .. result_arr.last loop
result_str := result_str || '+' || result_arr(x);
end loop;
dbms_output.put_line(substr(result_str, 2));
end print_res;
begin
loop
if sum_current = 0 then
proc(1, 1);
elsif sum_current < sum_target and
result_arr(result_arr.last) < num_limit then
tmp_int := result_arr(result_arr.last) + 1;
proc(tmp_int, 1);
else
if sum_current = sum_target and
result_arr(result_arr.last) <= num_limit then
--打印结果
print_res;
end if;
proc(null, -1);
if result_arr.count = 0 then
goto endflag;
end if;
tmp_int := result_arr(result_arr.last) + 1;
proc(tmp_int, 0);
end if;
end loop;
<<endflag>>
null;
end;
with t as
(select 1 a from dual union all
select 2 a from dual union all
select 3 a from dual union all
select 4 a from dual union all
select 5 a from dual union all
select 6 a from dual union all
select 7 a from dual union all
select 8 a from dual union all
select 9 a from dual),
t1 as (
select t.*,
dbms_aw.eval_number(substr(sys_connect_by_path(a, '+'), 2)) dd,
substr(sys_connect_by_path(a, '+'), 2) cc
from t
connect by nocycle a > prior a
and level <=4
)
select * from t1 where dd =10
sum_target integer := 172; --和为10
num_limit integer := 0; --可用的数字为1-9
type arr is table of integer index by binary_integer;
result_arr arr; --存放符合条件的数值的数值
tmp_int integer; --存放准备插入数组的数字
sum_current integer := 0; --当前数组中数值的和
sal_add_int integer :=0;
sal_add_int1 integer :=0;
vv integer :=0;
--用来操作数组的存储过程,add_int:传入的数值;
--add_type: 0:将add_int替换最后一个节点;1:添加到新的节点;-1:删除最后一个节点
procedure proc(add_int in integer, add_type in integer) is
begin
if add_type = 0 then
vv := result_arr(result_arr.last);
select sal into sal_add_int from t2 where id = vv;
select sal into sal_add_int1 from t2 where id = add_int;
sum_current := sum_current - sal_add_int + sal_add_int1;
result_arr(result_arr.last) := add_int;
vv:=0;
sal_add_int :=0;
sal_add_int1 :=0;
elsif add_type = 1 then
select sal into sal_add_int from t2 where id = add_int;
sum_current := sum_current + sal_add_int;
sal_add_int :=0;
result_arr(nvl(result_arr.last, 0) + 1) := add_int;
elsif add_type = -1 then
vv := result_arr(result_arr.last);
select sal into sal_add_int from t2 where id = vv;
sum_current := sum_current - sal_add_int;
result_arr.delete(result_arr.last);
vv:=0;
sal_add_int:=0;
end if;
end proc;
--打印结果
procedure print_res as
result_str varchar2(32767); --存放要打印的结果字符串
begin
result_str := null;
for x in 1 .. result_arr.last loop
result_str := result_str || '+' || result_arr(x);
end loop;
dbms_output.put_line(substr(result_str, 2));
end print_res;
begin
select count(*) into num_limit from t2;
loop
if sum_current = 0 then
proc(1, 1);
elsif sum_current < sum_target and
result_arr(result_arr.last) < num_limit then
tmp_int := result_arr(result_arr.last) + 1;
proc(tmp_int, 1);
else
if sum_current = sum_target and
result_arr(result_arr.last) <= num_limit then
--打印结果
print_res;
end if;
proc(null, -1);
if result_arr.count = 0 then
goto endflag;
end if;
tmp_int := result_arr(result_arr.last) + 1;
proc(tmp_int, 0);
end if;
end loop;
<<endflag>>
null;
end;
大概写了一下,不过这个对源数据的格式有要求,需要 id 依据 sal 从小到大的顺序逐次增加(可以新增一列)。这是根据上面的那个改了一下,还有其他实现方式,懒得写了