Nejbližší odpověď, kterou mohu poskytnout, je toto
set @cnt = 0;
set @cursum = 0;
set @cntchanged = 0;
set @uqid = 1;
set @maxsumid = 1;
set @maxsum = 0;
select
t.id,
t.name,
t.cnt
from (
select
id + 0 * if(@cnt = 30, (if(@cursum > @maxsum, (@maxsum := @cursum) + (@maxsumid := @uqid), 0)) + (@cnt := 0) + (@cursum := 0) + (@uqid := @uqid + 1), 0) id,
name,
@uqid uniq_id,
@cursum := if(@cursum + price <= 500, @cursum + price + 0 * (@cntchanged := 1) + 0 * (@cnt := @cnt + 1), @cursum + 0 * (@cntchanged := 0)) as cursum, if(@cntchanged, @cnt, 0) as cnt
from (select id, name, price from items order by rand() limit 10000) as orig
) as t
where t.cnt > 0 and t.uniq_id = @maxsumid
;
Jak to tedy funguje? Nejprve vybereme z položek 10 000 náhodně uspořádaných řádků. Poté sečteme ceny položek, dokud nedosáhneme 30 položek se součtem menším než 500. Když najdeme 30 položek, opakujeme proces, dokud neprojdeme všech 10 000 vybraných položek. Při nalezení těchto 30 položek ušetříme maximální nalezenou sumu. Nakonec tedy vybereme 30 položek s nejvyšším součtem (což znamená nejbližší k cílové 500). Nejsme si jisti, zda je to to, co jste původně chtěli, ale najdeme přesnou součet 500 by vyžadoval příliš mnoho úsilí na straně DB.