Det nærmeste svar, jeg kan give, er dette
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
;
Så hvordan virker det? Først vælger vi 10.000 tilfældigt ordnede rækker fra varer. Efter det summerer vi priser på varer, indtil vi når 30 varer med sum mindre end 500. Når vi finder 30 varer, gentager vi processen, indtil vi gennemgår alle de 10.000 udvalgte varer. Mens vi finder disse 30 varer, sparer vi maksimalt fundne beløb. Så til sidst vælger vi 30 varer med den største sum (betyder den tættest på målet 500). Ikke sikker på, om det var det, du oprindeligt ønskede, men at finde den nøjagtige sum på 500 ville kræve for meget indsats på DB-siden.