SQL ZOO:按字母顺序列出每个大陆和国家的名称。

7

我不明白为什么它不能是

Select x.continent, x.name
From world x
Where x.name <= ALL (select y.name from world y where x.name=y.name)
ORDER BY name

请问为什么必须是x.continent=y.continent而不是x.name=y.name?这与编程有关。

表格


你需要提供更多的背景信息来解释你的问题。你想要达到什么样的结果,才会让“它”必须是x.continent=y.continent?是因为当使用x.name=y.name时,你没有得到你想要的结果吗?还是因为你遇到了错误?请具体说明你的问题。 - OLIVER.KOO
@O.KOO 如果我使用 x.name=y.name,答案将是不正确的。 - teamking12
你想要什么样的答案或结果? - OLIVER.KOO
从表格中(我附上的图片)查询出每个大陆和按字母顺序排列的第一个国家的名称。这是 SQLZOO 的一个问题。@O.KOO - teamking12
如果您只需要每个大陆及其国家名称列表,并按照国家名称的字母顺序排序,那么您甚至不需要使用WHERE子句。 - OLIVER.KOO
@O.KOO 当然需要where子句。它需要查询每个大陆中的“第一个国家”,而不是每个大陆中的所有国家。 - teamking12
16个回答

30

当你使用x.name=y.name时,你在比较来自x的国家名称与来自y的国家名称,如果两个实例拥有相同的国家名称,那么就会返回完整的x表。

你需要使用x.continent=y.continent,因为你只想在它们共享相同大陆时才将来自x实例的国家名称与来自y实例的国家名称进行比较。

让我用一个例子一步步地说明这个问题:这里有一个名为world的表格,我随意填充了一些数据:

world: 

Select  x.continent, x.name
From world x
ORDER BY  name

continent       name
Asia            Afghanistan
Europe          Albania
Africa          Algeria  
Europe          Andorra
Africa          Angola
SouthAmerica    Bolivia
SouthAmerica    Brazil
Europe          Hungary
Asia            Japan
Africa          Nigeria
SouthAmerica    Peru
Asia            Taiwan

当您在子查询中不使用WHERE子句执行此查询时:

Select  x.continent, x.name
From world x
Where x.name <= ALL (select y.name from world y)
ORDER BY name

你会得到这个

continent   name
Asia        Afghanistan

这是因为where子句过滤掉了除一个国家外的所有国家。

where x.name <= (Afghanistan,Taiwan,Japan,
                 Albania,Hungary,Algeria,Nigeria,Andorra,
                 Angola,Bolivia,Peru,Brazil)

即,按字母顺序排列的国家中,第一个是阿富汗。

但由于我们想要获得每个大洲中的第一个国家,因此我们将在子查询中添加x.continent=y.continent

Select  x.continent, x.name
From world x
Where x.name <= ALL (select y.name from world y where x.continent=y.continent)
ORDER BY name

底层发生的事情是,现在只有在它们共享同一大洲的情况下,我们才将来自 x 的实例的国家名称与来自 y 的实例的国家名称进行比较。以亚洲为例:

日本被过滤掉,因为 Japan <= All(Afghanistan,Taiwan,Japan) 为false,因为日本不小于阿富汗(A在J之前)

台湾被过滤掉,因为 Taiwan <= All(Afghanistan,Taiwan,Japan) 为false,因为台湾不小于阿富汗。

阿富汗没有被过滤,因为 Afghanistan <= All(Afghanistan,Taiwan,Japan) 为true,因为阿富汗等于阿富汗

然而,如果您在子查询中使用 x.name=y.name,那么您实质上是将每个国家与其本身进行比较,它们都将包含在最终结果集中,因为所有国家名称都等于其本身的国家名称。

希望这可以帮助您,欢迎使用Stack Overflow。如果此回答或其他回答解决了您的问题,请标记它为已接受。


@O KOO 谢谢。感谢您的解释:D - teamking12
注意:ORDER BY name与此无关。 - quitprog

15
我试过这个,它也有效。
SELECT continent, MIN(name)
FROM world
GROUP BY continent
ORDER BY name

2

这是正确的答案:

Select continent,name 
from world x
Where x.name <= ALL(select y.name from world y
                    where x.continent=y.continent)
ORDER BY continent

0
列出每个大洲以及按字母顺序排名第一的国家名称。
选择大洲,名称 从世界 x 其中名称在(选择最小(名称) 从世界 y 其中 x.continent = y.continent)

你提供了一个代码示例,非常好。但是由于缺乏适当的格式,它可能会被忽略。为了改变这种情况,请查看如何使用Markdown或HTML格式化我的帖子?,特别是标题为“代码块”和“代码的语法高亮显示”的部分。 - nosurs

0

你可以用这种方式进行查询

    SELECT MIN(continent), MIN(name) 
    FROM world
    GROUP By continent

您的回答可以通过提供更多支持信息来改善。请[编辑]以添加更多细节,例如引用或文档,以便其他人可以确认您的答案是否正确。您可以在帮助中心中找到有关如何编写好答案的更多信息。 - Community

0

这个很简单,因为min函数会返回字母表顺序中的第一个单词。

SELECT continent, name FROM world x WHERE name = (SELECT min(name) FROM world y WHERE x.continent = y.continent );


0

针对以上问题可行的最简单查询:

从world表中选择continent和name的最小值,并按照continent分组;


这个答案已经被给出,并且并没有真正回答问题。 - Shmiel

0

选择洲名,最小名称 from 世界 按洲分组


0
with new as (
    select continent, name , row_number() over (partition by continent order by name) as row 
    from world
)

select continent,name
from new
where row = 1

欢迎来到SO!请编辑您的答案并添加一些解释性文字,说明它是如何工作的以及为什么与其他给出的答案不同。 - ahuemmer

0
select continent, name
from world x
where name = 
(select name from world y where x.continent= y.continent order by name limit 1)

只需在相关子查询中对元素进行排序,并使用 limit 选择第一个元素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接