Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

selecione 30 linhas aleatórias onde soma valor =x


A resposta mais próxima que posso fornecer é esta
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
;

Então, como funciona? No início, selecionamos 10 mil linhas ordenadas aleatoriamente de itens. Após isso somamos os preços dos itens até chegarmos a 30 itens com soma menor que 500. Quando encontramos 30 itens repetimos o processo até percorrermos todos os 10k itens selecionados. Ao encontrar esses 30 itens, economizamos a soma máxima encontrada. Então, no final, selecionamos 30 itens com maior soma (ou seja, o mais próximo da meta de 500). Não tenho certeza se era isso que você queria originalmente, mas encontrar o exato soma de 500 exigiria muito esforço no lado do banco de dados.