Вы можете использовать рекурсивный запрос, но так как это неполиномиальная проблема, производительность будет снижаться с увеличением количества записей.Первый запрос with
просто генерирует данные примера.В вашем случае вы бы, конечно, запросили вашу фактическую таблицу:
with tbl(key, value) as (
select 'A', 1 from dual union all
select 'B', 2 from dual union all
select 'C', 3 from dual union all
select 'D', 99 from dual union all
select 'E', 90 from dual
),
rec(greatest_key, greatest_single, key_count, keys, total) as (
select key,
value,
1,
key,
value
from tbl
union all
select tbl.key,
greatest(tbl.value, rec.greatest_single),
rec.key_count+1,
substr(rec.keys, 0, 1000) || ', ' || tbl.key,
rec.total + tbl.value
from rec
inner join tbl
on tbl.key > rec.greatest_key
and rec.total + tbl.value <= 102
),
ordered(total, keys, r) as (
select total, keys, row_number() over (
order by total desc, key_count desc, greatest_single desc)
from rec
)
select total, keys
from ordered
where r = 1
Часть ordered
предназначена только для получения "верхней" записи.
Смотрите, как она работает на rextester .
Если у вас Oracle 12c +, вы можете завершить запрос без использования ordered
:
select total, keys
from rec
order by total desc,
key_count desc
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY