2014-10-27 40 views
0

首先,我正在使用mySQL的世界数据库:http://dev.mysql.com/doc/world-setup/en/index.html如何混合并改进这个SQL语句?

我试图建立一个句子,返回来自每个大陆最不居住的国家,如果人口相同,则显示每个大洲的所有国家。

用下面的句子,我设法得到每个大陆中最少居住的国家的人口,但只有其中一个显示,并且国家显示不正确。

SELECT 
CASE 
    WHEN Continent="Europe" THEN "Europe" 
    WHEN Continent="Asia" THEN "Asia" 
    WHEN Continent="North America" THEN "North America" 
    WHEN Continent="South America" THEN "South America" 
    WHEN Continent="Africa" THEN "Africa" 
    WHEN Continent="Oceania" THEN "Oceania" 
    ELSE "Antarctica" 
END 
    AS Area, 
Name, 
    CONCAT(MIN(Population),"hb") AS "N habitantes"  
FROM Country 
GROUP BY Area; 

给出了这样的结果

'Africa'  , 'Angola'  , '0hb' 
'Antarctica' , 'Antarctica' , '0hb' 
'Asia'   , 'Afghanistan' , '286000hb' 
'Europe'  , 'Albania'  , '1000hb' 
'North America', 'Aruba'   , '7000hb' 
'Oceania'  , 'American Samoa', '0hb' 
'South America', 'Argentina'  , '2000hb' 

好了,代码是很愚蠢的,我想必须有一种方法来指示更好地为每个大陆上的查询必须返回至少居住的国家。我想知道它是否存在,因为只有7个大陆可以完成,但是如果它们是1000000 ...

有了这些句子,我将能够返回该大陆上最少居住的国家我表示,例如:

SELECT Name,Population FROM Country WHERE Population= 
(SELECT MIN(Population) FROM Country WHERE Continent="Antarctica"); 

返回:

'南极洲', '0'

'法国南方的领土', '0'

“布维岛 ' '0'

'赫德岛和麦当劳群岛', '0'

'英属印度洋领地', '0'

'南乔治亚岛和南桑威奇群岛',' 0'

‘美国本土外小岛屿’,‘0’

我认为必须有这两个句子混合的一种方法,它返回类似于以前的结果,每个大洲,所以返回结果是什么我一开始就在讲。我的意思是,如果在世界上唯一的大陆,其中南极洲和南美洲应该将其添加到先前的结果:

“福克兰群岛”,“2000”

“诺福克岛”,“2000”

“纽埃”,“2000”

“托克劳”,“2000”

我知道我可以使用UNION使得类似于第二个每个大洲的一句话,但再次,这是可行的,只是因为有只有7大洲。

有什么想法我错过了什么?谢谢你的帮助。

回答

-1

你可以通过这样的使用群体:

SELECT Name,Population FROM Country WHERE Population= 
(SELECT MIN(Population) FROM Country GROUP BY Continent); 
+0

谢谢您的回答序列号,但除非我已经理解错了,它不起作用。首先,子查询返回多于一行,所以它不能通过执行,我想你想把最后一行)放在国家之后,这样它就可以工作,但是这个世界上所有国家中人口最少的国家并不在每个大陆,只是显示每个大洲的一个国家。 – user2638180 2014-10-27 12:17:20

1
SELECT x.continent 
     , x.code 
     , x.name 
     , x.population 
    FROM country x 
    JOIN 
     (SELECT continent 
      , MIN(population) min_population 
      FROM country 
     GROUP 
      BY continent 
    ) y 
    ON y.continent = x.continent 
    AND y.min_population = x.population; 

输出:

+---------------+------+----------------------------------------------+------------+ 
| continent  | code | name           | population | 
+---------------+------+----------------------------------------------+------------+ 
| Antarctica | ATA | Antarctica         |   0 | 
| Antarctica | ATF | French Southern territories     |   0 | 
| Antarctica | BVT | Bouvet Island        |   0 | 
| South America | FLK | Falkland Islands        |  2000 | 
| Antarctica | HMD | Heard Island and McDonald Islands   |   0 | 
| Africa  | IOT | British Indian Ocean Territory    |   0 | 
| Asia   | MDV | Maldives          |  286000 | 
| Antarctica | SGS | South Georgia and the South Sandwich Islands |   0 | 
| North America | SPM | Saint Pierre and Miquelon     |  7000 | 
| Oceania  | UMI | United States Minor Outlying Islands   |   0 | 
| Europe  | VAT | Holy See (Vatican City State)    |  1000 | 
+---------------+------+----------------------------------------------+------------+ 
3

要获得每个大洲的人口最少的国家的名字,你需要确定这些国家。事情是这样的: -

SELECT Continent, MIN(Population) 
FROM Country 
GROUP BY Continent 

不好的一面是它不返回国名,你不能合法刚才添加的国家名称查询(MySQL不会出错,但结果是不确定的)。

因此,你可以使用上面作为一个子查询,并加入它对阵表,无论在大陆的名称和人口

SELECT b.Continent, b.Name, b.Population 
FROM 
(
    SELECT Continent, MIN(Population) AS Population 
    FROM Country 
    GROUP BY Continent 
) a 
INNER JOIN Country b 
ON a.Continent = b.Continent 
AND a.Population = b.Population 

一面是,如果一个以上的国家有在一个大陆同样的人口,结果将是奇怪的。

另一种选择是使用GROUP_CONCAT把所有的名字连在一起,在安装顺序,那么就使用SUBSTRING_INDEX抢第一个: -

SELECT Continent, SUBSTRING_INDEX(GROUP_CONCAT(Name ORDER BY Population), ',', 1), SUBSTRING_INDEX(GROUP_CONCAT(Population ORDER BY Population), ',', 1) 
FROM Country 
GROUP BY Continent 
这种方法的

一面是,如果一个国家的名称中包含用作分隔符的字符,结果可能很奇怪(默认是逗号)。

也有可能使用用户变量来人口有序的大陆内的序列号添加到国家,然后只要抓住那些拥有1