Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle PL/sql:计算所有可能的数字组合的总和_Sql_Oracle_Plsql_Plsqldeveloper - Fatal编程技术网

Oracle PL/sql:计算所有可能的数字组合的总和

Oracle PL/sql:计算所有可能的数字组合的总和,sql,oracle,plsql,plsqldeveloper,Sql,Oracle,Plsql,Plsqldeveloper,Oracle数据库 假设我有3个盒子,里面有不同数量的物品,盒子的数量是固定的 下面的方框id和QTY B101 5 B102 5 B103 4 存在一个容器,其中包含一定数量的物品 现有数量-2 货柜容量-15 现在,我想要所有可能的组合的总和,包括盒子1,盒子2,盒子3,现有数量 我将只选择sum

Oracle数据库

假设我有3个盒子,里面有不同数量的物品,盒子的数量是固定的

下面的方框id和QTY

B101 5
B102 5
B103 4
存在一个容器,其中包含一定数量的物品

现有数量-2

货柜容量-15

现在,我想要所有可能的组合的总和,包括盒子1,盒子2,盒子3,现有数量

我将只选择sum<容量最适合的组合

所有组合必须有现有数量的强制性,因为我们不能忽略这一点

本案的最终结果

第1箱+第2箱+现有数量5+5+2,容量15以内

需要PL/SQL块来执行相同的活动


我将在用户定义的记录表中获取box id和box qty

可能有更简单的方法,但我将使用递归CTE。下面是一个简单的SQL示例,带有额外的示例行:

create table boxes (id varchar2(4), qty number);

insert into boxes values ('B101',5);
insert into boxes values ('B102',5);
insert into boxes values ('B103',4);
insert into boxes values ('B104',9);
insert into boxes values ('B105',11);
insert into boxes values ('B106',2);
insert into boxes values ('B107',1);

with c (r, id, qty, lvl) as (
    -- anchor query
    select id as r, id, qty, 1 as lvl
    from boxes
    where qty + 2 < 15
    union all
    -- recursive query
    select c.r || ',' || b.id, b.id, b.qty+c.qty, c.lvl+1
    from boxes b
    join c on c.id < b.id
    where b.qty + c.qty + 2 < 15
    )
select r, lvl, qty 
from c
order by qty desc, lvl asc
;
这将显示所有组合,在顶部显示最佳配合。我在级别上添加了第二个排序,假设在平局的情况下,您希望每个容器的箱子数量最少。但您可能更喜欢每个容器的最大盒子数

我还对c.id 例如PL/SQL函数:

create or replace function fit_boxes(existing_qty in number, capacity in number)
return varchar2
is
    box_list varchar2(4000);
begin

    with c (r, id, qty, lvl) as (
        select id as r, id, qty, 1 as lvl
        from boxes
        where qty + existing_qty < capacity
        union all
        select c.r || ',' || b.id, b.id, b.qty+c.qty, c.lvl+1
        from boxes b
        join c on c.id < b.id
        where b.qty + c.qty + existing_qty < capacity
        )
    select r into box_list
    from c
    order by qty desc, lvl asc
    fetch first 1 row only
    ;

    return box_list;

exception when NO_DATA_FOUND then
  return 'No boxes fit'
end;
/

select fit_boxes(2,15) from dual;

最后,我猜你想要求和,这个问题似乎与背包问题密切相关。如果你有N个盒子,那么可能的组合总数似乎是2^N,这很快就会失控。例如:只有16个盒子,你已经有65536个可能的组合。你知道不同盒子的最大数量吗?另请参见:这非常有效。当我在select语句中直接使用框id而不是表名时,我将框id和QTY保存在一个大容量收集变量中,该变量是一个记录表。如何进行大容量收集变量的并集或自联接?我在模式中创建了类型,而不是在包中创建,上述问题得到了解决。你能解释一下你的代码的工作原理吗?好的,我更新了一些解释。递归CTE/分层查询可能非常混乱。