La réponse la plus proche que je puisse fournir est celle-ci
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
;
Alors comment ça marche ? Au début, nous sélectionnons 10 000 lignes ordonnées au hasard parmi les éléments. Après cela, nous additionnons les prix des articles jusqu'à ce que nous atteignions 30 articles avec une somme inférieure à 500. Lorsque nous trouvons 30 articles, nous répétons le processus jusqu'à ce que nous parcourions tous les 10 000 articles sélectionnés. En trouvant ces 30 articles, nous économisons la somme maximale trouvée. Donc, à la fin, nous sélectionnons 30 éléments avec la plus grande somme (c'est-à-dire le plus proche de l'objectif 500). Je ne sais pas si c'est ce que vous vouliez à l'origine, mais trouvez le exact une somme de 500 demanderait trop d'efforts du côté de la base de données.