美文网首页
SQLZOO练习--子查询: select中的select

SQLZOO练习--子查询: select中的select

作者: Ashin10 | 来源:发表于2020-05-02 22:19 被阅读0次

简介

sqlzoo是一个适合用于练习sql的题库网站
不要觉得页面丑而且无简体中文
如果做得完大部分题目比你听网课更有成效
补充:我是菜比

本练习的习题地址

https://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial/zh

练习

1. 列出每个国家的名字 name,其中人口 population 高于俄罗斯'Russia'的人口

子查询的入门,没什么难度

SELECT name FROM world
  WHERE population >
     (SELECT population FROM world
      WHERE name='Russia')

2. 列出欧洲每个国家 的人均GDP,其中人均GDP要高于英国'United Kingdom'的值。

注意是人均,因此where条件加上gdp/population

SELECT name FROM world
  WHERE gdp/population >
(SELECT gdp/population FROM world
  WHERE name='United Kingdom')
and 
  continent='Europe'

3. 列出 阿根廷Argentina 及 澳大利亚 Australia所在的洲中,所有国家的名字 name 及大洲 continent 。按国家名字升序排序

如果你没有忘记order by的话也不难写

SELECT name,continent  FROM world
  WHERE 
continent = 
(SELECT continent FROM world
  WHERE name = 'Argentina ')
or
continent = 
(SELECT continent  FROM world
  WHERE name = 'Australia')
order by name

4. 列出人口比加拿大Canada多,但比波兰Poland少的国家的名字name和人口population 。

无难度,不过结果竟然是空

SELECT name,population FROM world
  WHERE 
population > (SELECT population  FROM world  WHERE name = 'Canada')
ADN population < (SELECT population  FROM world   WHERE name = 'Poland')

5. 列出欧洲的国家名称name和每个国家的人口population。以德國的人口作为分母,以百分比%的形式显示

结果参考:

Albania 3%        //(占德国的3%的人口)
Andorra 0%        //(占德国的0%)

主要考察了concatround的用法
另外我还真的没有在所查询字段使用过子查询语句,长见识了...

SELECT name,
concat(
  round(
    (population*100/(select population from world where name = 'Germany')),0),
    '%'
) 
FROM world
  WHERE 
continent = 'Europe' 

6. 列出GDP比欧洲Europe全国都高的国家 [只需列出 name] (注意,有些国家的GDP是NULL)

根据页面的提示,因此需要设置条件gdp>0

SELECT name FROM world
  WHERE 
gdp >
ALL(SELECT gdp FROM world
  WHERE 
    continent = 'Europe'
    and
    gdp > 0
)

一开始我将gdp>0设置在主查询语句中,结果不显示数据
因为Europe中存在gdp = null,因此需要先排除Europe中的null
因此,如果遇到数据可能为null的查询也需要先将子查询中的数据排除null

7. 找出每个州中最大面积的国家,列出大洲名 continent, 国家名字 name 及面积 area。 (注意有些国家的面积AREA是NULL)

原题提示非常多,稍微修改下即可

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

分析: 设置条件,当主查询x的洲名与子查询y相同,且area非空时,比较主查询与子查询的area大小

如果使用group by+max()的情况

select 
continent,name,area
from world w1
where
area = 
(select max(area) from world w2 where w1.continent = w2.continent group by continent)

原理是一样的,不过我比较喜欢group by+聚合函数的写法,性能优略不知道

8. 列出洲名,和每个洲中按字母顺序第一的国家名。(即每洲只有1国)

select 
continent,name
from world w1
where
name = (select name from world w2 where w1.continent = w2.continent order by name limit 1)

不过不纠结于子查询,还有取巧的办法

select continent,min(name) from world group by continent

9. 列出洲内人口都少于等于 25000000 的国家,需要包含字段:国家名name,洲名continent 和人口数population

说实话这题有点搞,没看答案前没理解,而且不用聚合+group by我还真的写不出

select name,continent,population
from world w1
where 
(select max(population) from world w2 where w2.continent =  w1.continent group by continent)<=25000000

分析: 将聚合的结果当作不等式的左侧(作为条件)
如果单个洲内国家的最高人口超过25b,则丢弃结果
因此通过聚合+group by获取每个洲的最高人口,并与25b进行比较得出的便是需要的结果

10. 有些國家的人口是同洲份的所有其他國的3倍或以上。列出 國家名字name 和 洲份 continent。

这题我觉得问题描述有点问题,暂时放着吧
结果如下

name    continent
-----------------------
Brazil  South America
Russia  Eurasia

总结

  • 子查询需要只能返会单条结果,根据这个特性可以通过主查询的某个条件=子查询的某个条件来进行约束,使每次子查询都只获得单挑结果
  • 我真的讨厌写sql

相关文章

网友评论

      本文标题:SQLZOO练习--子查询: select中的select

      本文链接:https://www.haomeiwen.com/subject/ypskghtx.html