Reputation: 474
I have a table that contains a dataset similar to the one below. There are thousands of entries that have a group id and an amount.
+-------+--------+
| Group | amount |
+-------+--------+
| 1 | 10 |
| 1 | 15 |
| 1 | 11 |
| 1 | 5 |
| 1 | 100 |
| 2 | 200 |
| 2 | 8 |
| 2 | 12 |
| 2 | 23 |
| 2 | 40 |
| 2 | 40 |
| 2 | 40 |
| 3 | 3 |
| 3 | 3 |
+-------+--------+
For each group, I need the (rounded) average of the top three entries with the highest amount within the group. If there are less than three entries for the group, the average is based on the available entries.
The potential table could look like, e.g. group #1: (100 + 15 + 11)/3 = 42 :
+-------+--------+
| Group | amount |
+-------+--------+
| 1 | 42 |
| 2 | 92 |
| 3 | 3 |
+-------+--------+
There can be 1 or more entries for each group and the amounts are positive integers but they can have the same value.
I've played around with Group by and order by but it don't seem to get it right. Any help is appreciated. Thanks.
Upvotes: 0
Views: 120
Reputation: 1269513
Most databases support the ANSI standard row_number()
function, which can help you solve this problem. Something like this will work in most databases:
select `group`, cast(0.5 + avg(amount) as int) as RoundedAverage
from (select t.*,
row_number() over (group by "group" order by amount desc) as seqnum
from t
) t
where seqnum <= 3
group by `group`;
If you don't have row_number()
in your database, you can do the work with a subquery or some other way, although an id
column is useful for this purpose.
Upvotes: 1