美文网首页
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