SQL order by and list - sql

I am fairly new to SQL and i have tried my hardest to code this, but it does not seem to work for me so help would be appreciated very much.
The question states that i need to list the total number of books published by each publisher and then list them from highest and lowest using the publisher code.
I have gotten this far;
SELECT COUNT (pub_code)
FROM Library_Books
GROUP BY pub_code
ORDER BY pub_code
Any help would be appreciated whatsoever

SELECT kb_pub_code, COUNT (kb_pub_code)
FROM Library_Books
GROUP BY kb_pub_code
ORDER BY 2

You are very close:
SELECT kb_pub_code, COUNT(*) TotalBooks
FROM Library_Books
GROUP BY kb_pub_code
ORDER BY TotalBooks DESC
TotalBooks is an alias for the count column, which is counting the total number of rows for each kb_pub_code
You can reference a column alias in your ORDER BY: ie.ORDER BY TotalBooks DESC
Note, if books can be repeated in the Library_Books table, you may want a DISTINCT count. Something like:
SELECT kb_pub_code, COUNT(DISTINCT title) TotalBooks
FROM Library_Books
GROUP BY kb_pub_code
ORDER BY TotalBooks DESC

SELECT kb_pub_code
,COUNT (*) as 'TotalBooks'
FROM Library_Books
GROUP BY kb_pub_code
ORDER BY TotalBooks desc
Edit: with the additional information of possible duplicates you may wish to use a CTE.
With DistinctList as(
Select Distinct kb_pub_code as 'PubCode'
,kb_title as 'Title'
FROM Library_Books)
Select PubCode
,Count(*) as 'TotalBooks'
From DistinctList
Group by PubCode
ORDER BY TotalBooks desc

ORDER BY DESC will sort in descending order. The publisher code should be included in the result set (SELECT) otherwise you would not know which publisher is the count for.
SELECT kb_pub_code, COUNT (kb_pub_code)
FROM Library_Books
GROUP BY kb_pub_code
ORDER BY COUNT(kb_pub_code) DESC

Related

SQL - return coumn value based on max column count

I have an SQL query where I can look up the maximum occurrence of a column. It works fine for what I needed, but now need to expand on this to only return the name of the column.
There's likely a way to improve my original query but I haven't been able to work it out.
select COMMUNITY_AREA_NUMBER, count(*) as CRIMES
from CHICAGO_CRIME_DATA
group by COMMUNITY_AREA_NUMBER
order by CRIMES desc
limit 1
My basic question is, how can I re-write this to only return the COMMUNITY_AREA_NUMBER?
I've tried to restructure as:
select COMMUNITY_AREA_NUMBER from CHICAGO_CRIME_DATA
where count(*) as CRIMES group by COMMUNITY_AREA_NUMBER order by CRIMES desc limit 1
I've also tried to incorporate a MAX function, but I don't seem to be getting anywhere with it.
edit:
Apparently I've just learned something inner queries. I needed to keep my original query and create an outer query that request something from that result.
select COMMUNITY_AREA_NUMBER from
(select COMMUNITY_AREA_NUMBER, count(*) as CRIMES
from CHICAGO_CRIME_DATA
group by COMMUNITY_AREA_NUMBER
order by CRIMES desc
limit 1)
Is this what you want?
SELECT COMMUNITY_AREA_NUMBER
FROM CHICAGO_CRIME_DATA
GROUP BY COMMUNITY_AREA_NUMBER
ORDER BY COUNT(*) DESC
LIMIT 1;
This returns a single community number having the most crime records. I have simply moved COUNT(*) from the select clause, where you don't want it, to the ORDER BY clause.

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.

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

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) .

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 ..