这个问题有点是my previous one的后续问题。它也基于SQLZOO's "SELECT within SELECT tutorial"。这次是关于任务#8 。
首先,一个可接受的解决方案:
SELECT w1.name, w1.continent FROM world w1
WHERE w1.population > ALL(
SELECT w2.population*3 FROM world w2
WHERE w2.continent=w1.continent and w2.name<>w1.name)
这次相关查询在逻辑中根深蒂固。
此查询是否仍然可以
答案 0 :(得分:2)
所以任务8说:有些国家的人口是其邻国(在同一个大陆)的三倍以上。给各个国家和大陆。
我觉得有点不清楚。哪个是邻居?这是非洲大陆的所有国家吗?如果是,则下一个问题是我们是否与最小邻居或最大邻居进行比较。让我们说它是最大的邻居。然后查询将是这样的
select name, continent
from world w1
where w1.population > (select max(3*w2.population)
from world w2
where w2.continent = w1.continent
and w2.name <> w1.name)
否则,如果它将是所有邻居的3倍,那么就是这个
select name, continent
from world w1
where w1.population > (select 3*sum(w2.population)
from world w2
where w2.continent = w1.continent
and w2.name <> w1.name)
希望它有所帮助。
编辑:Oracle SQL手册(E26088-01)说明了所有功能:
将值与列表中的每个值进行比较或由查询返回。
示例:
SELECT * FROM employees
WHERE salary >=
ALL ( 1400, 3000)
ORDER BY employee_id;
首先进行聚合,然后进行比较,我们将其减少为一个比较。给定示例表中的结果是相同的。但针对所有国家的查询实际上可能会产生不同的结果。毕竟我必须说你的查询更好。如果你在一个大陆拥有1百万,3.5百万和11百万人口的国家,那么实际上第二个国家是第一个国家的3倍,第三个国家是第二个国家的3倍。我的查询只会比较第二个国家和第三个国家,但您的查询也会比较第一个国家和第二个国家。
答案 1 :(得分:1)
对于此特定查询,您需要每个大洲上的最大和第二大值。我会用窗口函数来处理它:
select w.continent,
max(case when seqnum = 1 then w.name end) as name
from (select w.*,
row_number() over (partition by continent order by population desc) as seqnum
from world w
) w
where seqnum in (1, 2)
group by continent
having max(case when seqnum = 1 then population end) > 3*max(case when seqnum = 2 then population end)
好的,我承认,考虑到问题的根源,这可能有点先进。
所以,这是一种使用连接而不是相关子查询的方法:
我认为以下是您的逻辑:
select w.name, w.continent
from world w join
(SELECT w.continent, maxpopulation,
max(case when population <> maxpopulation then population end) as secondmax
FROM world w join
(select continent, max(population) as maxpopulation
from world
group by continent
) c
on w.continent = c.continent
group by w.continent, maxpopulation
) wc
on w.continent = wc.continent and w.population = maxpopulation
where population >= 3*secondmax
所以答案是&#34;是的,你可以在没有相关子查询的情况下做到这一点。&#34;在大多数常见情况下,您可以使用连接和分组重写相关子查询。