简体   繁体   中英

MySQL SUM of LIMIT(3) rows with GROUP BY

Good people, need a bit of a help with MySQL. Tried few solutions online but could get it right.

I have this simple table.

name    amount
john  | 150
john  | 100
john  | 100
john  | 150
jack  | 300
jack  | 100
jack  | 100

Basically, I have to get the users that have sum of 500 in at least 3 rows(ordered by the highest amount). The correct answer should only return jack because only he has sum of 500 in 3 records(ordered by highest). Where else john has 500 in total sum, 3 of his highest amounts would only return 400(150+150+100), so the query doesn't return john .

SELECT 
*,
SUM(amount) as sums
FROM (SELECT * FROM transfer GROUP BY name ORDER BY amount DESC LIMIT 3) as ttl
GROUP BY name
HAVING sums >= 500

It works fine(no errors at least), but the second select(the one inside the bracket) only returns the first row.

Any help is highly appreciated.

Let me assuming that you have another column that is a unique id. Then you can do this as:

select distinct t1.name
from transfer t1 left join
     transfer t2
     on t1.name = t2.name and t1.id < t2.id left join
     transfer t3
     on t1.name = t3.name and t2.id < t3.id
where t1.amount + coalesce(t2.amount, 0) + coalesce(t3.amount, 0) >= 500;

This is not wildly efficient for larger tables. For that, use variables to enumerate the values:

select name
from (select t.*,
             (@rn := if(@n = name, @rn + 1,
                        if(@n := name, 1, 1)
                       )
             ) as rn
      from transfer cross join
           (select @n := '', @rn := 0) params
      order by name, amount desc
     ) t
where rn <= 3
group by name
having sum(amount) >= 500;

This also has the benefit that it does not rely on an id column.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM