Die nächste Antwort, die ich geben kann, ist diese
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
;
Wie funktioniert es? Zuerst wählen wir 10.000 zufällig geordnete Zeilen aus Artikeln aus. Danach summieren wir die Artikelpreise, bis wir 30 Artikel mit einer Summe von weniger als 500 erreichen. Wenn wir 30 Artikel finden, wiederholen wir den Vorgang, bis wir alle 10.000 ausgewählten Artikel durchgegangen sind. Beim Finden dieser 30 Artikel speichern wir die maximale Fundsumme. Am Ende wählen wir also 30 Artikel mit der größten Summe aus (d. h. am nächsten an den Zielvorgaben von 500). Nicht sicher, ob Sie das ursprünglich wollten, aber den genauen zu finden Eine Summe von 500 würde DB-seitig zu viel Aufwand erfordern.