Selecting top results from SQL Count query, including table join - Oracle - sql

I have this query currently, which selects the top "number of pickups" in descending order. I need to filter only the top 10 rows/highest numbers though. How can I do this?
I have tried adding 'WHERE ROWNUM <= 10' at the bottom, to no avail.
SELECT customer.company_name, COUNT (item.pickup_reference) as "Number of Pickups"
FROM customer
JOIN item ON (customer.reference_no=item.pickup_reference)
GROUP BY customer.company_name, item.pickup_reference
ORDER BY COUNT (customer.company_name) DESC;
Thanks for any help!

You need to subquery it for the rownum to work.
SELECT *
FROM
(
SELECT customer.company_name, COUNT (item.pickup_reference) as "Number of Pickups"
FROM customer
JOIN item ON (customer.reference_no=item.pickup_reference)
GROUP BY customer.company_name, item.pickup_reference
ORDER BY COUNT (customer.company_name) DESC
)
WHERE rownum <= 10
You could alternatively use ranking functions, but given the relative simplicity of this, I'm not sure whether I would.

The solution by using the rank is something like this :
select customer.company_name, COUNT (item.pickup_reference) from (
select distinct customer.company_name, COUNT (item.pickup_reference) ,
rank() over ( order by count(item.pickup_reference) desc) rnk
from customer
JOIN item ON (customer.reference_no=item.pickup_reference)
group by customer.company_name, item.pickup_reference
order by COUNT (customer.company_name) )
where rnk < 10
Using the 'rownum' to get the top result doesn't give the expected result, because it get the 10 first rows which are not ordred, and then order them (Please notify this on a comment on Andrew's response, I don't have the right to add the comment) .

Related

LIMITING MAX VALUES IN SQL

I am completely rewriting this question, I just cant crack it
IDB DB2 SQL
(from a Chicago Crime Dataset)
Which community area is most crome prone?
When I use this code, it does correctly count and sort the data
select community_area_number as community_area_number, count(community_area_number) as total_area_crime
from chicago_crime_data
group by community_area_number
order by total_area_crime desc;
the problem is, it lists all the data descending, but no matter what MAX statement I use, either in the select or the order by statement, it wont show just the max values.
The max values are 43, so I would like to to show both 'community_area_numbers' that have 43.
Instead it shows the entire list.
Here is a screenshot
also, yes I understand I can just do a LIMIT 2 command, but that would be cheating since I manually checked that there are 2 max values, but if this data changed or i didnt know that, it doesnt solve anything
thanks in advance
What you would be looking for is the standard SQL clause FETCH WITH TIES;
select community_area_number, count(*) as total_area_crime
from chicago_crime_data
group by community_area_number
order by total_area_crime desc
fetch first row with ties;
Unfortunately, though, DB2 doesn't support WITH TIES in FETCH FIRST.
The classic way (that is before we had the window functions RANK and DENSE_RANK) is to use a subquery: Get the maximum value, then get all rows with that maximum. I am using a CTE (aka WITH clause) here in order not to have to write everything twice.
with counted as
(
select community_area_number, count(*) as total_area_crime
from chicago_crime_data
group by community_area_number
)
select community_area_number, total_area_crime
from counted
where total_area_crime = (select max(total_area_crime) from counted);
(Please note that this is a mere COUNT(*), because we want to count rows per community_area_number.)
Like #topsail mentioned. You could use a rank function.
From the table you have above you could do the following
SELECT t.* FROM
(
SELECT *,
RANK() OVER (Order by Total_Area_Crime DESC) rnk
from
table1
)t
WHERE t.rnk = 1
db fiddle
So your full query should look something like this:
With cte AS (
SELECT MAX(COMMUNITY_AREA_NUMBER) AS COMMUNITY_AREA_NUMBER,
COUNT(COMMUNITY_AREA_NUMBER) AS TOTAL_AREA_CRIME
FROM CHICAGO_CRIME_DATA
GROUP BY COMMUNITY_AREA_NUMBER
ORDER BY TOTAL_AREA_CRIME DESC;
)
SELECT t.* FROM
(
SELECT *,
RANK() OVER (Order by Total_Area_Crime DESC) rnk
from
cte
)t
WHERE t.rnk = 1
It turns out the professor did want us to use the Limit command.
Here is the final answer:
SELECT COMMUNITY_AREA_NUMBER, COUNT(ID) AS CRIMES_RECORDED
FROM CHICAGO_CRIME_DATA
GROUP BY COMMUNITY_AREA_NUMBER
ORDER BY CRIMES_RECORDED DESC LIMIT 1;
thanks to all those who responded :D

QL: Find Top 2 and reverse order

I am having the IMDB database; I am looking for the top two years in which most movies were produced, and I have to sort them chronologically after the years and print only the years.
I am trying this to compute the list and sort it 'the other way around' afterwards but I cannot order by anthing in the last 'order by' statement because in the FROM-statement I dont refer to any tables and instead open the next statement. It says "unknown column topTwo" as well so that I cannot order my results accordingly.
What am I doing wrong?
SELECT *
FROM
(SELECT m.year, COUNT(*)
FROM movies as m
GROUP BY m.year
ORDER BY m.year DESC) AS topTwo
ORDER BY **topTwo** ASC
LIMIT 2;
I think you are looking for this:
SELECT topTwo.year
FROM (SELECT m.year, COUNT(*) as cnt
FROM movies m
GROUP BY m.year
ORDER BY COUNT(*) DESC
LIMIT 2
) topTwo
ORDER BY year ASC;
Notes:
The LIMIT goes in the subquery.
The COUNT(*) is given an alias.
The ORDER BY in the subquery is based on the count.
The ORDER BY in the outer query is based on the year.
You only seem to want the year, so the outer query only select that column.

Sum of five lowest values

How can I find the sum of the lowest five points in the Point column
and group by ID
Table
The desired results should be;
Results
No idea where to start
Thanks
select a.ID, SUM(a.points) from(select ID , points,row_number() over
(partition by ID order by POINTS) as rownum_returned from your_table) a where
a.rownum_returned<6 group by a.ID;
Read about row_number() function here
If I've to do that I would solve it with a subquery.
In SQL server I will do subquery that retrieve the 5 lower point
Select Top 5 id, point from table
Order by point asc
Note: the keyword TOP that limit the result to the first 5
Note 2: order by point asc will order the result putting in top the lowest value
Now I use the query as subquery to complete the activity
Select id, sum (point) from
(Select top 5 id,point from table order by point asc) group by id
This should work

Select 2nd and 3rd newest row in an SQL table

i'm currently developing a news-site.
So here is the problem. I want to select the 2nd and 3rd row in a TOP 3.
SELECT TOP 3 * FROM News ORDER BY Date DESC;
I want to remove the 1st row and only return the 2nd and 3rd row.
Can anyone help?
Try this:
SELECT TOP 2 FROM
( SELECT TOP 3 * FROM News ORDER BY Date DESC ) xx
ORDER BY Date
SQLFiddle: http://www.sqlfiddle.com/#!3/dbb7e/5
You can also do this generically using window functions:
select n.*
from (SELECT n.*, row_number() over (order by date desc) as seqnum
FROM News n
) n
where n.seqnum >= 2 and n.seqnum <= 3;
I just offer this as a general solution. You can also ensure that you get everything from the second date (in case there are more than two items on that date) by using dense_rank() rather than row_number().
If you know that no two dates will be the same, you could add
where date not in (select max(date) from News)
Or you could look at rowid if you know that the first item will have rowid=0, for example if you created a temp table with the results of your initial query.
I assume, you somehow know what you Top 3 news are by ordering by date descending.
Therfore you should use the LIMIT clause with an OFFSET [For sqlite]
SELECT * FROM News ORDER BY Date DESC LIMIT 2 OFFSET 1;
Select top 2 * from News cross apply (select top 3 from news order by date desc)x

Sort by count SQL reporting services

I have a simple query in a tabloid control that gets all the leads in one month. I then use the tabloid control to group them into lead source. And then I have an associated count column. I want to sort my report on the count descending, without doing it in the query. I keep getting an error saying you cannot sort on an aggregate.
Thanks.
you can do one more thing..
just write your query in subquery part and write order by clause in outer query.
(suppose you have group by query as follow-
select lead_source, count(*) cnt
from your_table
group by lead_source
)
so you can do as follow -
select lead_source, cnt from (
select lead_source, count(*) cnt
from your_table
group by lead_source
)
order by cnt
this your_table and group by column list you have to edit accordingly your table structure ..