Reputation: 1981
I am a beginner in MySQL and I've stumbled upon this for the past few days now.
Let's say I have a country table as seen below:
code name continent Population
ABW Aruba North America 103000
AFG Afghanistan Asia 22720000
AGO Angola Africa 12878000
AIA Anguilla North America 8000
ALB Albania Europe 3401200
AND Andorra Europe 78000
ARG Argentina South America 37032000
This table has information of continents and population of each country.
How do I find the country with nth highest population in each continent?
For a specific scenario, How do I find the country with the thrid highest population in each continent?
I checked many SO questions, including this link. But could not find the answer for this problem. Any help would be greatly appreciated!
Upvotes: 2
Views: 1136
Reputation: 84
with result as
(
select code,name,continent,population,dense_rank() over( order by population ) as rnk
from dbo.country
)
select population,continent from result where rnk=3 group by continent,population ;
If you want the 2nd highest population then enter the rnk in where clause as 2 and so on ..
Upvotes: 3
Reputation: 49260
One option to do this is using variables.
select code,name,continent,population
from (
select c.*,
@prevPopulation:=@curPopulation,
@curPopulation:=population,
@prevContinent:=@curContinent,
@curContinent:=continent,
case when @curContinent = @prevContinent and @prevPopulation <> @curPopulation then @rn:=@rn+1
when @curContinent = @prevContinent and @prevPopulation = @curPopulation then @rn:=@rn
else @rn:=1 end as rank
from country c,
(select @rn := 0, @curContinent := '',@prevContinent := '', @curPopulation:=0,@prevPopulation:=0) r
order by continent,population desc
) x
where rank = 3 --replace it with the nth highest value needed
This query uses 4 variables
1) @curContinent which is initially set to an empty string. Thereafter the select
assigns the current row's continent.
2) @prevContinent which is initially set to an empty string. Thereafter the select
sets it to @curContinent value (which is an empty string initially).
3) @curPopulation which is initially set to 0. Thereafter the select
assigns the current row's population.
4) @prevPopulation which is initially set to 0. Thereafter the select
sets it to the @curPopulation (which is 0 for the first time and so on).
order by
clause is important here to desingate the current and previous rows based on continent and population. This would handle ties too as it would assign the same rank to all the countries within a continent with the same population.
Run the inner query initially to see how the variables are set, which would clarify things for you.
Upvotes: 1
Reputation: 1269773
Assuming no countries have the same population, then one method is to count the number of countries that have the same or higher population and see when the count is 3:
select c.*
from country c
where (select count(*)
from country c2
where c2.continent = c.continent and c2.population >= c.population
) = 3;
Upvotes: 1