2

我对 SQLZoo 上的一个问题很感兴趣。这是一个“每组最大 n”的问题。我想了解发动机是如何工作的。

一个名为 bbc 的表包含每个国家的名称、世界地区和人口:

英国广播公司(名称,地区,人口)

给定的任务是选择每个地区人口最多的国家,显示其名称、地区和人口。

提供的解决方案是:

SELECT region, name, population FROM bbc x
  WHERE population >= ALL
    (SELECT population FROM bbc y
        WHERE y.region=x.region
          AND population>0)

1.主要问题。我觉得这有点让人费解。我想了解引擎是如何处理这个的,因为乍一看似乎存在某种相互依赖(x 取决于 y,y 取决于 x)。引擎是否遵循某种递归来产生最终选择?还是我错过了什么,例如 x 或 y 实际上是固定的?

2. 次要问题。奇怪的是,当我将“AND population>0”从括号中拉出并将其单独留在底部时,8 个结果中缺少一个区域(欧洲/俄罗斯)。为什么?我不明白。

事实上,当我尝试对世界数据库(可从与 Sakila 相同页面上的 mySQL 网站获得)进行查询时,行为是不同的:括号中的人口 > 0,我得到 6 个区域。6 在这个数据库中是正确的数字,因为“SELECTcontinent FROM country GROUP BY 大陆”显示了七个大陆,其中一个是南极洲,其中包括 5 个“国家”,所有国家的人口均为 0。

所以这似乎是对的。

SELECT continent, `name`, population FROM country X
WHERE population >= ALL 
(SELECT population FROM country Y
WHERE Y.`Continent` = X.`Continent`)
AND population>0

另一方面,当我像在 SQLZoo 上一样将“人口 > 0”拉回括号时,我还得到了 5 个零的国家(“属于南极洲”的国家)。无论我指定 x.population 还是 y.population,我都会得到零。

continent      name                                          population  
-------------  --------------------------------------------  ------------
Antarctica     Antarctica                                               0
Antarctica     French Southern territories                              0
Oceania        Australia                                         18886000
South America  Brazil                                           170115000
Antarctica     Bouvet Island                                            0
Asia           China                                           1277558000
Antarctica     Heard Island and McDonald Islands                        0
Africa         Nigeria                                          111506000
Europe         Russian Federation                               146934000
Antarctica     South Georgia and the South Sandwich Islands             0
North America  United States                                    278357000

非常期待这些问题的见解!

祝大家有个美好的一周。

:)

笔记:

  1. 作为参考,问题是此页面上的第 3a 号:http: //old.sqlzoo.net/1a.htm ?answer=1

  2. 一个线程提到同一查询的“greatest-n-per-group”问题: MySQL world database Trying to Avoid subquery

  3. 世界数据库可在此处获得: http: //dev.mysql.com/doc/index-other.html

4

1 回答 1

1
  1. 主要问题。我觉得这有点让人费解。我想了解引擎是如何处理这个的,因为乍一看似乎存在某种相互依赖(x 取决于 y,y 取决于 x)。引擎是否遵循某种递归来产生最终选择?还是我错过了什么,例如 x 或 y 实际上是固定的?

这不是递归。从 MySQL 文档中查看。他们对问题的解决方案相当于这个

SELECT region, name, population FROM bbc x
  WHERE population = 
    (SELECT max(population) FROM bbc y
        WHERE y.region=x.region
          )
  1. 次要问题。奇怪的是,当我将“AND population>0”从括号中拉出并将其单独留在底部时,8 个结果中缺少一个区域(欧洲/俄罗斯)。为什么?我不明白。

微小的变化(如上面 ypercube 所建议的)工作

SELECT region, name, population FROM bbc x
  WHERE population >= ALL
    (SELECT population FROM bbc y
        WHERE y.region=x.region
          AND population IS NOT NULL)

这个查询

SELECT region, name, population FROM bbc x
  WHERE population is null

返回一行。不知道为什么人口应该可以为空,但没有仔细研究它的其余部分。否则,查询应该可以在没有>0

此外,这与每组最大 n 不同。在那个问题中,你试图找到前 N 个项目,而不仅仅是前一个项目。

于 2012-08-13T00:15:47.633 回答