Reputation: 15369
How can I select across multiple rows based on a particular column value. For example I have a structure like this
+--+----+-----+
|id|data|count|
+--+----+-----+
|1 |text|30 |
+--+----+-----+
|1 |text|1 |
+--+----+-----+
|1 |text|25 |
+--+----+-----+
|1 |text|12 |
+--+----+-----+
|1 |text|50 |
+--+----+-----+
|2 |text|5 |
+--+----+-----+
|2 |text|2 |
+--+----+-----+
|2 |text|100 |
+--+----+-----+
|2 |text|50 |
+--+----+-----+
|2 |text|1000 |
+--+----+-----+
|3 |text|2 |
+--+----+-----+
|3 |text|4 |
+--+----+-----+
|3 |text|6 |
+--+----+-----+
|3 |text|8 |
+--+----+-----+
And I want to select three of every ID--the "top" 3 based on the highest values in the count
column so that I'll end up with:
+--+----+-----+
|id|data|count|
+--+----+-----+
|1 |text|30 |
+--+----+-----+
|1 |text|25 |
+--+----+-----+
|1 |text|50 |
+--+----+-----+
|2 |text|100 |
+--+----+-----+
|2 |text|50 |
+--+----+-----+
|2 |text|1000 |
+--+----+-----+
|3 |text|4 |
+--+----+-----+
|3 |text|6 |
+--+----+-----+
|3 |text|8 |
+--+----+-----+
I am essentially stuck on the first WHERE clause: I don't want the rows where count
is above a particular value as that could return more than 3 results. I can do a limit 3 and sort by count, but that will only work for one id. How can I do this for every distinct id in my table?
Upvotes: 1
Views: 1143
Reputation: 247820
You should be able to implement a windowing function like row_number()
to get the top 3 for each id
:
select id, data, "count"
from
(
select id, data, "count",
row_number() over(partition by id order by "count" desc) seq
from yourtable
) d
where seq <= 3
order by id, "count";
Upvotes: 3
Reputation: 17920
SELECT "id",data,"count"
FROM
(SELECT "id",data,"count" rank() OVER (partition by "id" ORDER BY "count" DESC) as rn
FROM
your_table) t
WHERE rn <= 3
ORDER BY "id","count" desc
Upvotes: 1