SQL ORDER BY with column number or aggregate function - sql

I've got 2 different results when I try ORDER BY with column number and with an aggregate function. What is the difference between these 2 methods? ( I thought they'd have the same output)
List the 1978 films by order of cast list size. There're 3 tables below:
movie(id, title, yr, director)
actor(id, name)
casting(movieid, actorid, ord)
Answer 1 using ORDER BY with column number:
SELECT title
,COUNT(a.id)
FROM movie m
,casting c
,actor a
WHERE m.id=movieid
AND a.id=actorid
AND yr=1978
GROUP BY title
ORDER BY 2 DESC
Using COUNT(a.id). Everything is the same except the last line
...
ORDER BY COUNT(a.id) DESC

I would suggest you to make a subquery and order that for the clean result

I think Jester has it. Here's an example for you:
select title, actor_count from (
SELECT title
,COUNT(a.id) actor_count
FROM movie m
,casting c
,actor a
WHERE m.id=movieid
AND a.id=actorid
AND yr=1978
GROUP BY title) subquery
order by actor_count

Related

Very common problem, very simple query in MySQL, but no so much in Microsoft SQL [duplicate]

This question already has answers here:
Get top 1 row of each group
(19 answers)
SQL Server - GROUP BY on one column
(4 answers)
Closed last year.
The object is to get the top activity that takes too much time per activity:
In mysql it should be easy:
select description, reference, person, max(minutes)
group by description
Result should bring back:
Description
Reference
Person
Minutes
Activity A
AA32343
Abe
10
Activity B
BB34345
Boris
8
Activity C
CCsdeee
John
12
But in Microsoft SQL, it wont run, 'cause the group by does not have all the columns in the select...
What is the equivalent to the mysql query in MS SQL? If i add all the columns i need in the group by, i will get all the rows, which is not what i want
This is a very common problem, can someone find the answer and post the query and explain it in a way that the answer can be applied to almost all similar problems?
Rows in table have info like:
Description
Reference
Person
Minutes
Activity A
AA32343
Abe
10
Activity A
AA77340
Wilson
9
Activity A
AA56341
Carl
4
Activity B
BB34345
Boris
8
Activity B
BB94342
Jane
6
Activity B
BB64343
Martha
3
Activity C
CCsdeee
John
12
Activity C
CCs5ee4
Peter
10
Activity C
CCskee5
Saul
4
Use row_number():
select * from (select description, reference, person, minutes,
row_number() over(partition by description order by minutes desc) rn from table_name
) a where rn=1
That is an invalid group by query in fact that you are doing in MySQL. How do you decide for example, it is reference 'AA32343' for 'Activity A'? Probaly just by ignoring from which row it comes. Then you could simply use an aggregation on those columns as well:
select description, min(reference) reference, min(person) person, max(minutes)
from myTable
group by description;
Or if you meant those fields come from the row with max(minutes), then:
select t.*
from myTable t
inner join (
select description, max(minutes) maxMin
from myTable
group by description) tmp on t.description = tmp.description and t.Minutes = tmp.maxMin;
Using an analytic window function
with cte as
(select *, max(minutes) over (partition by description) as max_minutes
from your_table)
select description, reference, person, minutes
from cte
where minutes=max_minutes;
Issue here is that you are omitting elements, as you don't seem to care which Reference and Person to show for each grouping.
One way to get your desired results is with a CTE to get Max minutes per Description, and then append the other columns.
For this example I'm getting the first Reference and Person ordered by Description:
;with cte as
(
select Description,
Minutes = max(Minutes)
from myTable MT
group by Description
)
Select C.Description,
R.Reference,
R.Person,
C.Minutes
From cte C
Cross Apply
(
Select top 1 T.Reference,
T.Person
From myTable T
where T.Description = C.Description
order by T.Description
) R

Retrieving inner table records in Postgres when using MAX COUNT

I'm trying to learn PostgreSQL with the IMDB database and I can't seem to figure out how to include the names of the movie with the largest cast.
I have three tables to work with
Table movie with mov_id, mov_title, mov_year
Table actor with act_id, act_name
Table movie_cast with act_id, mov_id, role
I tried the code below to print out the MAX of the Count which works as expected.
select max(cast_number) from (
select m.mov_id as movie_id, m.mov_title as movie_title, count(*) as cast_number
from movie_cast
join movie m using (mov_id)
group by m.mov_id, m.mov_title
) As innerTable;
When I try to include the movie_id, and movie_title into the result, it asks me to include those fields in a GROUP BY clause or in an aggregate function. I tried including the fields into the GROUP BY clause:
select innerTable.movie_id, innerTable.movie_title, max(cast_number) from (
select m.mov_id as movie_id, m.mov_title as movie_title, count(*) as cast_number
from movie_cast
join movie m using (mov_id)
group by m.mov_id, m.mov_title
) As innerTable
group by innerTable.movie_id, innerTable.movie_title;
But this here, gives me all the records, just like what the innerTable gave me. I could have used ORDER BY and LIMIT 1, but I also want to include the names if more than one movie has the max value.
Can someone point me to the right direction on how to achieve the functionality to find the film(s) with the largest cast?
Use RANK:
with cte as (
select m.mov_id as movie_id, m.mov_title as movie_title, count(*) as cast_number,
rank() over (order by count(*) desc) rnk
from movie_cast
inner join movie m using (mov_id)
group by m.mov_id, m.mov_title
)
select mov_id, mov_title, cast_number
from cte
where rnk = 1;
This would return the movie records having the highest cast number.

Get most frequent value with SQL query

I'm trying to write an SQL query where I find the value that occurs the most frequently.
So far, I have this:
SELECT GENRE, COUNT(*) AS Frequency
FROM BooksRead
GROUP BY GENRE
This gives me output like this:
Anthropological 1
Biography 7
Crime 4
Essay 2
I want the returned result to be 7. I've tried using TOP 1 but my Java compiler doesn't seem to like it.
The ANSI SQL syntax would be:
SELECT GENRE, COUNT(*) AS Frequency
FROM BooksRead
GROUP BY GENRE
ORDER BY COUNT(*) DESC
FETCH FIRST 1 ROW ONLY;
Not all databases support that syntax. Many support LIMIT:
SELECT GENRE, COUNT(*) AS Frequency
FROM BooksRead
GROUP BY GENRE
ORDER BY COUNT(*) DESC
LIMIT 1;
However, the exact syntax depends on the database you are using.
You can also use ANSI standard window functions:
SELECT *
FROM (SELECT GENRE, COUNT(*) AS Frequency,
ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC) as seqnum
FROM BooksRead
GROUP BY GENRE
) g
WHERE seqnum = 1;
If you want ties then use RANK() instead of ROW_NUMBER().

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.

How to find the highest populated instance in a column in SQL

So I have a table (person), that contains columns such as persons name, age, eye-color, favorite movie.
How do I find the most popular eye color(s), returning just the eye color (not the count) using SQL (Microsft Access), without using top as there might be multiple colours with the same count.
Thank you
SELECT
EyeColor
FROM
Person
GROUP BY
EyeColor
HAVING
COUNT(*) = (
SELECT MAX(i.EyeColorCount) FROM (
SELECT COUNT(*) AS EyeColorCount FROM Person GROUP BY EyeColor
) AS i
)
In Access, I think you need something on the lines of:
SELECT First(t.Eyecolor) AS FirstOfEyeColor
FROM (SELECT p.EyeColor, Count(p.EyeColor) AS C
FROM Person p
GROUP BY p.EyeColor
ORDER BY Count(p.EyeColor) DESC) AS t;