Daniel
Daniel

Reputation: 47

Using SQL query into ORDER BY clause

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

Answers (3)

user330315
user330315

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

developer_hatch
developer_hatch

Reputation: 16224

Sorry this should work

SELECT * 
FROM   sometable
ORDER BY name
FETCH FIRST 10 ROWS ONLY

Upvotes: 0

MT0
MT0

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

Related Questions