试图学习 SQL,但我被一个简单的查询困住了

时间:2021-03-16 22:35:25

标签: mysql sql

我刚刚安装了 MySQL,我对学习 SQL 感兴趣。 MySQL 的默认数据库之一是“World”。该数据库有 5 列:ID、名称(城市名称)、CountryCode、District 和 Population。我尝试了一个简单的查询,该查询应该显示每个国家/地区人口最少的城市的 ID。

USE world;

SELECT ID, MIN(POPULATION), COUNTRYCODE
FROM CITY
GROUP BY COUNTRYCODE
order by ID

问题是查询结果显示的是国家的第一个ID,与该国人口最少的城市ID无关。

例如:AFG 国家代码有 4 个城市:

+----+----------------+-------------+------------+------------+
| ID |      CITY      | COUNTRYCODE | CITY_AGAIN | POPULATION |
+----+----------------+-------------+------------+------------+
|  1 | Kabul          | AFG         | Kabol      |    1780000 |
|  2 | Qandahar       | AFG         | Qandahar   |     237500 |
|  3 | Herat          | AFG         | Herat      |     186800 |
|  4 | Mazar-e-Sharif | AFG         | Balkh      |     127800 |
+----+----------------+-------------+------------+------------+

AFG国家查询结果为

+----+------------+-------------+
| ID | POPULATION | COUNTRYCODE |
+----+------------+-------------+
|  1 |     127800 | AFG         |
+----+------------+-------------+

ID 应该是 4,而不是 1。

那么,为什么查询结果在 ID 列上不正确?

2 个答案:

答案 0 :(得分:0)

您正在按 COUNTRYCODE 分组,因此所有 5 行都归为一个。

您对 POPULATION 使用了 grouping function,所以这是正确的。

COUNTRYCODE 总是相同的,所以它总是正确的。

但是,查询没有关于选择哪个 ID 的说明。您尚未指定 grouping function

怎么办?

我不明白您想要按 ID 对结果进行排序的原因。按 MIN(POPULATION)COUNTRYCODE 排序更有意义。例如:

SELECT ID, 
       MIN(POPULATION) AS SmallestCityPopulation, 
       COUNTRYCODE
FROM CITY
GROUP BY COUNTRYCODE
order by SmallestCityPopulation ASC

这是有道理的。

答案 1 :(得分:0)

您的查询是做什么的:

  1. 您选择城市表中的所有行。
  2. 您汇总这些行以获得每个国家/地区的一个结果。
  3. 你出示身份证。 ID???一个国家有很多城市,因此有很多ID。你想展示哪个?最小值?最大值?您不会告诉 DBMS 是哪个。这应该会导致错误(并且它会让您将 sql 模式设置为 ONLY_FULL_GROUP_BY)。照原样,MySQL 会默默地应用 ANY_VALUE(id),即它任意选择一个不是您想要的 ID。

你不能一步完成你想做的事。您需要两个步骤:

  1. 找出每个国家的最低人口数量。
  2. 查找与该人口匹配的城市。

一个(简单的)解决方案:

SELECT *
FROM city
WHERE (countrycode, population) IN
(
  SELECT countrycode, MIN(population)
  FROM city
  GROUP BY countrycode
);

另一种解决方案遵循不同的路径:选择不存在该国家人口较少的城市的所有行:

SELECT *
FROM city
WHERE NOT EXISTS
(
  SELECT NULL
  FROM city smaller_city
  WHERE smaller_city.countrycode = city.countrycode
  AND smaller_city.population < city.population
);
相关问题