2017-01-03 80 views
1

我是MySQL的初学者,在过去的几天里我偶然发现了这一点。如何在每个mysql查询组中获得第n个最高分项

比方说,我有一个国家表如下所示:

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 

此表有每个国家的陆地和人口的信息。

如何找到每个大陆人口最多的国家?

对于一个特定的情况,我如何找到每个大陆第三人口最多的国家?

我检查了很多SO问题,包括这个link。但找不到这个问题的答案。任何帮助将不胜感激!

回答

1

一个选项来做到这一点使用变量。

select code,name,continent,population 
from (
select c.*, 
@prevPopulation:[email protected], 
@curPopulation:=population, 
@prevContinent:[email protected], 
@curContinent:=continent, 
case when @curContinent = @prevContinent and @prevPopulation <> @curPopulation then @rn:[email protected]+1 
    when @curContinent = @prevContinent and @prevPopulation = @curPopulation then @rn:[email protected] 
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 

此查询使用4个变量

1),其最初被设置为一个空字符串@curContinent。此后select分配当前行的大陆。

2)@prevContinent最初设置为空字符串。此后,select将其设置为@curContinent值(最初为空字符串)。

3)@curPopulation最初设置为0.此后select分配当前行的总体。

4)@prevPopulation最初设置为0.之后,select将其设置为@curPopulation(第一次为0,依此类推)。

order by条款对于设计基于大陆和人口的当前和以前的行很重要。这也可以处理联系,因为它可以将相同的排名赋予一个拥有相同人口的大陆上的所有国家。

最初运行内部查询以查看变量是如何设置的,这将为您澄清事情。

Sample Demo

1

假设没有国家有相同的人口,再一个方法是计算具有相同或更高的人口的国家的数量和看到当计数为3:

select c.* 
from country c 
where (select count(*) 
     from country c2 
     where c2.continent = c.continent and c2.population >= c.population 
    ) = 3; 
+0

诚然,这是做一个漂亮的调皮事,但假设没有在一个大陆的2个国家有着相同的,明显估计的情况,似乎是这样的混乱。先生,所有应有的尊重。已经有人说过......我没有想到更好的解决方案。 –

+2

一种替代方法是使用变量。或者是一个正确支持'row_number()','rank()'等的数据库。 –

1
 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 ; 

如果你想在第二高的人口然后输入where子句中RNK为2等..

+0

这也是我的想法。其他人更干净。 – Edward

相关问题