使用 min/max 的子查询

Subqueries using min/max

一些国家的人口是其任何邻国(同一大陆)人口的三倍多。给出国家和大洲。

From https://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial, question 10

我试过这个:

SELECT w.name, w.continent 
FROM world w
WHERE w.population/3 > (SELECT min(w2.population) 
                      FROM world w2
                      WHERE w2.continent = w.continent);

这个解决方案似乎有效:

SELECT w.name, w.continent 
FROM world w
WHERE w.population > (SELECT 3 * MAX(w2.population) 
                      FROM world w2
                      WHERE w2.continent = w.continent AND
                            w2.name <> w.name
                     );

我试图理解我的解决方案中的逻辑缺陷。

为什么使用 max() 而不是 min(),因为我们要比较人口是否是非洲大陆人口最少国家的 3 倍?

min/max 场景中是否需要 w2.name <> w.name。为什么?

more than three times that of any of their neighbours

也就是说,同一个大陆上人口第二多的国家必须少于三分之一,而且每个大陆只有一个国家有资格。 (大陆上的最低人口数不相关。)

第二个查询获取同一大陆上除外部查询 (w2.name <> w.name) 之外的所有国家/地区,找到人口最多的国家并乘以 3。如果仍然低于该国家/地区的人口外部查询,它通过了条件。

除此之外,虽然优雅 SQL,但查询开销很大,因为 相关子查询 必须计算一次每一行。这个应该更便宜:

SELECT *
FROM  (
   SELECT DISTINCT ON (continent)
          name, continent, population
        , lead(population) OVER (PARTITION BY continent ORDER BY population DESC) AS next_population
   FROM   world
   ORDER  BY continent, population DESC
   ) sub
WHERE  population > 3 * next_population;

db<>fiddle here