Jawaban terdekat yang bisa saya berikan adalah ini
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
;
Jadi bagaimana cara kerjanya? Pada awalnya kami memilih 10k baris yang dipesan secara acak dari item. Setelah itu kita jumlahkan harga barang sampai kita mencapai 30 barang dengan jumlah kurang dari 500. Ketika kita menemukan 30 barang kita ulangi prosesnya sampai kita menelusuri semua 10rb barang yang dipilih. Saat menemukan 30 item ini, kami menyimpan jumlah maksimum yang ditemukan. Jadi pada akhirnya kami memilih 30 item dengan jumlah terbesar (artinya yang paling dekat dengan target 500). Tidak yakin apakah itu yang Anda inginkan, tetapi menemukan tepat jumlah 500 akan membutuhkan terlalu banyak usaha di sisi DB.