如何混合和改进这个SQL句子?

时间:2014-10-27 12:09:05

标签: mysql sql

首先,我使用mySQL的世界数据库:http://dev.mysql.com/doc/world-setup/en/index.html

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

通过以下句子,我设法让每个大陆中一个人口最少的国家的人口,但只有一个显示,国家显示不正确。

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个大陆才可行。

知道我错过了什么吗?谢谢你的帮助。

3 个答案:

答案 0 :(得分: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的那些国家。

答案 1 :(得分: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 |
+---------------+------+----------------------------------------------+------------+

答案 2 :(得分:-1)

你可以像这样使用group:

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