Reputation: 157
I have a table with all the cars that have crossed one road during one week. Now I want know what are the 10 most observed cars in that road.
My idea is:
1) Group the cars and count the number of times that they have crossed the road:
select nplate, count('x') from observations group by nplate;
I have to do this because I can have the same car observed multiple times in the same week.
2) Order this group by count from highest to lowest.
3) Take the first 10 of those results.
But I don't know how to do the last two steps.
Thank you.
Upvotes: 2
Views: 2284
Reputation: 12486
I'm surprised no one has given the answer using a window (analytic) function ROW_NUMBER()
:
SELECT nplate, observation_cnt FROM (
SELECT nplate, COUNT(*) AS observation_cnt
, ROW_NUMBER() OVER ( ORDER BY COUNT(*) DESC ) AS rn
FROM observations
GROUP BY nplate
) WHERE rn <= 10
ORDER BY rn;
If there are two (or more) values of nplate
with the same number of observations, and all have the 10th most observations, and it's important that you get all, then you'll want to use the window function RANK()
instead:
SELECT nplate, observation_cnt FROM (
SELECT nplate, COUNT(*) AS observation_cnt
, RANK() OVER ( ORDER BY COUNT(*) DESC ) AS rn
FROM observations
GROUP BY nplate
) WHERE rn <= 10
ORDER BY rn;
(It's possible you'll want DENSE_RANK()
as well!)
In short, window functions give you a flexibility that the ROWNUM
and FETCH FIRST
solutions do not.
Upvotes: 0
Reputation: 31648
This works for Oracle 12c and above:
SELECT nplate,
COUNT(*)
FROM observations
GROUP BY nplate
ORDER BY COUNT(*) DESC
FETCH FIRST 10 ROWS ONLY;
Upvotes: 1
Reputation: 238078
You can order by count(*) desc
. The Oracle way to limit the result to 10 rows is to use a subquery followed by where rownum < N
:
SELECT *
FROM (
SELECT nplate
, count(*)
from observations
group by
nplate
order by
count(*) desc
) sub
WHERE rownum <= 10
Your example uses count('x')
, which counts the number of rows where 'x' is not null
. That doesn't hurt but it doesn't make sense either.
Upvotes: 0