SQL ZOO 按字母顺序列出每个大陆和首先出现的国家/地区名称

问题描述 投票:0回答:17

我很困惑为什么不能

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.Continue=y.Continental 而不是 x.name=y.name 吗?

mysql sql correlated-subquery
17个回答
31
投票

当您使用

x.name=y.name
时,如果两个实例具有相同的国家/地区名称,则您将比较 x 中的国家/地区名称与 y 中的国家/地区名称。这基本上只会返回完整的表 x。

您想要使用

x.continent=y.continent
,因为您只想将 x 中实例的国家/地区名称与 y 中实例的国家/地区名称(如果它们共享同一大陆)进行比较。

让我用一个例子逐步说明这一点: 这里我们有一个表格世界,我填充了一些数据:

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 中的实例的国家/地区名称进行比较(如果它们共享同一大陆)。因此以亚洲大陆为例:

Japen 被过滤掉是因为

Japan <= All(Afghanistan,Taiwan,Japan)
是假的,因为日本不小于或等于阿富汗(A 在 J 之前)

台湾被过滤掉是因为

Taiwan <= All(Afghanistan,Taiwan,Japan)
是假的,因为台湾并不小于或等于阿富汗。

阿富汗没有被过滤掉,因为

Afghanistan <= All(Afghanistan,Taiwan,Japan)
是正确的,因为阿富汗等于阿富汗

但是,如果您在子查询中使用

x.name=y.name
,那么您实际上是将每个国家/地区与其自身进行比较,它们都将包含在您的最终结果集中,因为所有国家/地区名称都等于其本身的国家/地区名称。

我希望这对您有所帮助,并欢迎来到 Stack Overflow。如果此答案或任何其他答案解决了您的问题,请将其标记为已接受。”


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
投票
 select A.continent, A.name 
 from
 (Select  x.continent, x.name, RANK() OVER(PARTITION BY x.continent ORDER BY x.name 
 asc)AS Rank  
 From world x
 group by  x.continent, x.name)A
 where
 Rank = 1

0
投票

这个很简单,因为 min func 会按字母顺序返回第一个单词。

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


0
投票

这也会产生正确的答案。

SELECT continent, name
FROM world a
WHERE name <= ALL(SELECT name FROM world b
               WHERE a.continent = b.continent)

0
投票

这里有一个注释 - 对于这个问题的正确答案,ORDER BY 是不必要的,对于最简单的解决方案,您所需要的只是:

SELECT continent, name
FROM world w1
WHERE w1.name <= ALL(SELECT name 
                       FROM world w2
                       WHERE w1.continent=w2.continent)

0
投票

按字母顺序列出每个大陆和首先出现的国家/地区名称。

选择大陆、名称 来自世界x 其中名称 (选择 min(名称) 来自 y 世界 其中 x. 大陆 = y. 大陆)


0
投票
SELECT
    continent, name
FROM
    world x
WHERE
    name <= ALL(SELECT name FROM world y WHERE x.continent=y.continent ORDER BY name )
ORDER BY continent

返回一个有序国家名称列表,然后返回该列表的第一个条目,最后按洲对外部选择查询进行排序。


0
投票

另一种使用rank()函数的方法也有效

select continent, name
from
(
    select continent, name, rank() over (partition by continent order by continent, name) as rn
    from world
    group by continent, name
    order by rn
) as a 
where rn = 1
order by continent

0
投票

您可以通过以下方式查询

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

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

0
投票

适用于上述问题的最简单查询:

选择大陆,分钟(名称) 来自世界 按大陆分组;


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 对相关子查询中的元素和第一个元素进行排序即可。


0
投票

从世界中选择大陆,分钟(名称) 按大陆分组


0
投票

块引用

选择不同的大陆, (从世界中选择名称 y 其中 x. 大陆 = y. 大陆 限制 1) 来自世界x


-2
投票
SELECT continent, name 
FROM world as x
WHERE name = ALL(SELECT min(name)
                 FROM world y
                 WHERE x.continent = y.continent);
© www.soinside.com 2019 - 2024. All rights reserved.