Reputation: 47
I have tables USERS
and REPORTS
. In the REPORTS
table, I have a column user_id
so I can count how many reports the users gave. What I want to do is to get first 10 users that gave the most reports.
I thought about the next query:
SELECT
*
FROM
(SELECT users.id
FROM users
ORDER BY (SELECT count(*)
FROM reports
WHERE user_id = "users.id") DESC)
WHERE
ROWNUM <= 10;
But, I don't know how to use the ID that was returned from the main query into subquery.
I use Oracle 11g.
Later edit I managed to sort the results with GROUP BY:
SELECT * FROM(SELECT user_id, count(*) as count1 FROM reports GROUP BY
user_id ORDER BY count1 DESC) WHERE ROWNUM <= 10
Upvotes: 0
Views: 62
Reputation:
This can be done by combining group by
with a window function:
select u.*, r.num_reports
from users u
join (
select user_id,
count(*) as num_reports,
dense_rank() over (order by count(*) desc) as rnk
from reports
group by user_id
) r on u.id = r.user_id and r.rnk <= 10
order by r.num_reports desc;
The derived table (the "inner" select) counts the number of reports per user and also ranks those rows based on the number of reports. The highest number will get rank = 1, the second highest 2 and so on. Those users with a rank higher then 10 will be filtered out in the join condition. Note that this can potentially return more then 10 users if there are users in the "top-10" that have the same number of reports.
Upvotes: 1
Reputation: 16224
Sorry this should work
SELECT *
FROM sometable
ORDER BY name
FETCH FIRST 10 ROWS ONLY
Upvotes: 0
Reputation: 167972
SELECT *
FROM (
SELECT u.id
FROM users u
INNER JOIN
(
SELECT user_id,
count(*) AS num_reports
FROM reports
GROUP BY user_id
) r
ON ( u.id = r.user_id )
ORDER BY r.num_reports DESC
)
WHERE ROWNUM <= 10;
or, more simply:
SELECT *
FROM (
SELECT user_id
FROM reports
GROUP BY user_id
ORDER BY COUNT(*) DESC
)
WHERE ROWNUM <= 10;
Upvotes: 0