为什么这个相关的子查询工作? (在Select 7中选择SQLZOO)

时间:2017-10-25 08:18:01

标签: sql

所以你不必去寻找它,他们为问题集呈现的数据看起来像这样,表格被称为world

name        continent   area    population  gdp
Afghanistan Asia        652230  25500100    20343000000
Albania     Europe      28748   2831741     12960000000
Algeria     Africa      2381741 37100000    188681000000
Andorra     Europe      468     78115       3712000000
Angola      Africa      1246700 20609294    100990000000

他们提供了一个练习,您可以使用查询在每个大洲中按区域选择最大的国家/地区。他们为你做了大部分工作,所以得到答案并不难。这是正确的查询:

SELECT continent, name, area FROM world x
  WHERE area >= ALL
   (SELECT area FROM world y
    WHERE y.continent=x.continent
      AND area>0)

我能理解它的工作必须发生什么,但不是为什么。 y.continent = x.continent必须通过某种花哨的GROUP BY,但是...这个课程没有解释它,我真的很想了解幕后发生的事情。

2 个答案:

答案 0 :(得分:1)

它不是循环或分组。让我们在查询中将行集表示为别名为x

name        continent   area    population  gdp
Afghanistan Asia        652230  25500100    20343000000
Albania     Europe      28748   2831741     12960000000
Algeria     Africa      2381741 37100000    188681000000
Andorra     Europe      468     78115       3712000000
Angola      Africa      1246700 20609294    100990000000

现在让我们添加一个"包含"的额外列。子查询 1 ,外部x值替换为:

name        continent   area    population  gdp          subquery
Afghanistan Asia        652230  25500100    20343000000  (select area FROM world y WHERE y.continent='Asia' AND area>0)
Albania     Europe      28748   2831741     12960000000  (select area FROM world y WHERE y.continent='Europe' AND area>0)
Algeria     Africa      2381741 37100000    188681000000 (select area FROM world y WHERE y.continent='Africa' AND area>0)
Andorra     Europe      468     78115       3712000000   (select area FROM world y WHERE y.continent='Europe' AND area>0)
Angola      Africa      1246700 20609294    100990000000 (select area FROM world y WHERE y.continent='Africa' AND area>0)

让我们代表子查询返回的结果:

name        continent   area    population  gdp          subquery
Afghanistan Asia        652230  25500100    20343000000  (652230)
Albania     Europe      28748   2831741     12960000000  (28748,468)
Algeria     Africa      2381741 37100000    188681000000 (2381741,1246700)
Andorra     Europe      468     78115       3712000000   (28748,468)
Angola      Africa      1246700 20609294    100990000000 (2381741,1246700)

现在,对于每一行,我们将area列与子查询返回的每个值进行比较。那就是ALL力量 - WHERE条款只有在所有这些比较都成立的情况下才能满足。比较的性质(>=)意味着它在每个大陆中具有最大area的国家的所有比较中都是正确的。

1 由于它是一个相关的子查询,它每行有效地评估一次,所以我认为在每行上显示评估的内容是合理的基础。请注意,一个简单的实现可能实际上一次评估一个子查询,因此它将例如收集欧洲(和非洲)的所有区域,同时处理整个外部查询。

答案 1 :(得分:0)

您只是希望子查询返回特定大陆的area值。换句话说,您希望比较某个国家/地区的area与所有位于同一个大洲的国家/地区的area

例如,对于第二行,在评估条件时,将28748与序列(28748, 468)中的所有值进行比较。该子序列返回该序列,它认为您只想与欧洲国家进行比较。

编辑:您询问嵌套查询如何执行group by。答案是:它没有。由于数据每个大陆只有一个国家,面积最大,我们似乎可以执行该组。但是,如果我们有不同的数据:

name        continent   area    population  gdp
--------------------------------------------------------
Afghanistan Asia        652230  25500100    20343000000
Pakistan    Asia        652230  2500100     2034300000

然后我们返回一行continent值的两行,因为它们都满足您希望areacontinent最大的国家/地区的条件。