MySQL SELECT。 LIMIT来自一列的值的数量

时间:2014-03-20 07:20:40

标签: mysql

任务:从MySQL标准数据库“世界”中选择人口超过一百万的所有城市,将国家数量限制为10个。 如果我这样做:

SELECT country.Name, city.Name, city.Population
FROM country
INNER JOIN city
  ON country.Code = city.CountryCode
WHERE city.Population >= 1000000
LIMIT 10;

它产生了这个:

+-------------+--------------+------------+
| Name        | Name         | Population |
+-------------+--------------+------------+
| Afghanistan | Kabul        |    1780000 |
| Algeria     | Alger        |    2168000 |
| Angola      | Luanda       |    2022000 |
| Argentina   | Buenos Aires |    2982146 |
| Argentina   | La Matanza   |    1266461 |
| Argentina   | Córdoba     |    1157507 |
| Armenia     | Yerevan      |    1248700 |
| Australia   | Sydney       |    3276207 |
| Australia   | Melbourne    |    2865329 |
| Australia   | Brisbane     |    1291117 |
+-------------+--------------+------------+
例如,阿根廷重复了3次。我需要将国家/地区数量限制为10,而不是行数。 由于我需要所有城市,因此GROUP BY不会这样做,我不需要将它们分组。

预期结果如下:

+--------------------+----------------------------+------------+
| Name               | Name                       | Population |
+--------------------+----------------------------+------------+
| Afghanistan        | Kabul                      |    1780000 |
| Algeria            | Alger                      |    2168000 |
| Angola             | Luanda                     |    2022000 |
| Argentina          | Buenos Aires               |    2982146 |
| Argentina          | La Matanza                 |    1266461 |
| Argentina          | Córdoba                   |    1157507 |
| Armenia            | Yerevan                    |    1248700 |
| Australia          | Sydney                     |    3276207 |
| Australia          | Melbourne                  |    2865329 |
| Australia          | Brisbane                   |    1291117 |
| Australia          | Perth                      |    1096829 |
| Azerbaijan         | Baku                       |    1787800 |
| Bangladesh         | Dhaka                      |    3612850 |
| Bangladesh         | Chittagong                 |    1392860 |
| Brazil             | São Paulo                 |    9968485 |
| Brazil             | Rio de Janeiro             |    5598953 |
| Brazil             | Salvador                   |    2302832 |
| Brazil             | Belo Horizonte             |    2139125 |
| Brazil             | Fortaleza                  |    2097757 |
| Brazil             | Brasília                   |    1969868 |
| Brazil             | Curitiba                   |    1584232 |
| Brazil             | Recife                     |    1378087 |
| Brazil             | Porto Alegre               |    1314032 |
| Brazil             | Manaus                     |    1255049 |
| Brazil             | Belém                     |    1186926 |
| Brazil             | Guarulhos                  |    1095874 |
| Brazil             | Goiânia                   |    1056330 |
| United Kingdom     | London                     |    7285000 |
| United Kingdom     | Birmingham                 |    1013000 |
+--------------------+----------------------------+------------+

如您所见,无论有多少个城市,国家数量都是10个。

当然,我的数据库是不同的。为了简单,通用和可用性,我使用了“世界” 在真正的数据库中,我也对“country”进行了一些过滤。

5 个答案:

答案 0 :(得分:0)

我希望这会起作用

SELECT country.Name, city.Name, city.Population
FROM country
LEFT JOIN city
  ON country.Code = city.CountryCode
WHERE city.Population >= 1000000
AND city.id IN (SELECT id FROM city WHERE city.Population >= 1000000 AND country.Code = city.CountryCode LIMIT 10);

答案 1 :(得分:0)

//So sorry try this query

SELECT country.Name, city.Name, city.Population
FROM country
LEFT JOIN city
  ON country.Code = city.CountryCode
WHERE city.Population >= 1000000 and country.Code IN(SELECT distinct CountryCode FROM city WHERE Population >= 1000000 LIMIT 10);

答案 2 :(得分:0)

为子查询中的每个唯一国家/地区生成临时行级别ID,并使用where temp_row_num is <= 10等where条件从中选择行。

示例

select
       /*uq_country_row_num, */ 
       country_name, city_name, population
from (
  select country_name, city_name, population
    , case when @pn=(@cn:=country_name) 
           then @r:=(@r + 1) 
           else @r:=1
      end as uq_country_row_num
    , @pn:=@cn as temp_cn
  from population, 
       (select @pn:='', @cn:='', @r:=0) country_rown_nums
  -- use order by country_name if the result set is un-ordered
  order by
     country_name
) all_results
where
  uq_country_row_num <= 10
;

如果您希望将变量/*uq_country_row_num, */作为输出的一部分,则可以取消注释。

示例 @ SQL Fiddle


修改: 来自评论:

  

您的意思是每个国家/地区10行或最多10个国家/地区的所有记录?

     

确切地说,“来自最多10个国家/地区的所有记录”。

select
  country_id,
  country_name, city_name, population
from (
  select 
    country_name, city_name, population
    , case when @pn=(@cn:=country_name) 
           then @country_id:=@country_id 
           else @country_id:=(@country_id + 1)
      end as country_id
    , @pn:=@cn as temp_cn
  from population, 
       (select @pn:='', @cn:='', @row_num:=0, @country_id:=0) country_row_nums
  order by country_name
) all_results
where
  country_id <= 10
;

示例2 @ SQL Fiddle

答案 3 :(得分:0)

尝试一次

SELECT city.Name, city.Population, newcountry.name
FROM city
INNER JOIN 
(select distinct Name,Code
 from country limit 10) newcountry
  ON newcountry.Code = city.CountryCode
WHERE city.Population >= 1000000;

答案 4 :(得分:0)

没有一个答案奏效。所以我不得不使用以下请求:

SELECT co.Code, co.Name, ci.Name, ci.Population
  FROM city ci
    INNER JOIN (
      SELECT DISTINCT co.Code, co.Name
        FROM country co
          INNER JOIN city ci
          ON ci.countryCode = co.Code
        WHERE ci.Population > 1000000
        ORDER BY co.Name
        LIMIT 10
    ) co
    ON ci.countryCode = co.Code
  WHERE ci.Population > 1000000;

对我来说似乎相当笨拙而且效率不高(注意条件的重复),但由于缺乏更好的方法,这是唯一的解决方案。

感谢大家的回答。