私が提供できる最も近い答えはこれです
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
;
それで、それはどのように機能しますか?最初に、アイテムからランダムに並べられた10k行を選択します。その後、合計が500未満の30アイテムに達するまでアイテムの価格を合計します。30アイテムが見つかったら、選択した10,000個のアイテムすべてをウォークスルーするまでこのプロセスを繰り返します。これらの30個のアイテムを見つけている間、見つかった最大の合計を保存します。したがって、最後に、合計が最大の30個のアイテムを選択します(ターゲット500に最も近いことを意味します)。それが最初に望んでいたものかどうかはわかりませんが、正確を見つけます。 合計500は、DB側で非常に多くの労力を必要とします。