zoukankan      html  css  js  c++  java
  • (十五)子查询


    子查询(sub query),查询是建立别的查询结果之上的,也就是一个 select 语句中包含另外一个 select 语句 ;


    分类

    有两类:按照位置分,按照查询结果分 ;

    按照位置分子查询(select 子语句)在外部查询语句(select 父语句)中出现的位置 ;

    • From 子查询 :子查询跟在 from 之后 ;
    • where 子查询:子查询出现在 where 条件中 ;
    • exists 子查询:子查询出现在 exists 里面 ;

    按照查询结果分根据查询得到的结果进行分类 ;

    • 标量子查询:子查询得到的结果是 一行一列

    • 列子查询:子查询得到的结果是 一列多行

    • 行子查询:子查询得到的结果是 一行多列(多行多列)

      上面几个出现的位置都是在 where 之后 ;

    • 表子查询:子查询得到的结果是 多行多列

      出现的位置在 from 之后 ;


    标量子查询

    案列:知道班级名字,查询出该班所有学生 ;

    分析:但是学生表中,只有班级 id ,没有班级名字,因此,需要先查出班级 id ,再拿着 id 去查学生 ;

    其中查询班级 id 的操作,就是 标量子查询 ,因为它查出来的结果是一行一列

    -- 第一步,根据班级id查询学生
    select * from student where c_id = ? ;
    
    -- 第二步 ,查询班级 id
    select id from class where name = '软件工程2021' ;
    
    -- 合并
    select * from student where c_id = (select id from calss where name = '软件工程2021') ;
    

    标量子查询

    案列:查询所有在读(名字在班级表中)的学生 ;

    分析: 学生表中的有的学生是往届的,我们现在需要查询出在读的 ;

    我们需要去查询班级表,拿到所有的班级id,然后去学生表中,根据id查询出学生 ;

    -- 查询对应的学生
    select * from student where c_id in (?) ;
    
    -- 查询所有班级的id
    select id from calss ;
    
    -- 拼接在一起
    select * from student where c_id in (select id from calss ) ;
    
    

    使用 in ,顺便提一下 mysql 失败的设计 anysomeall

    anyin 的意思一样,都是其中一个的意思, 但是在使用的时候前面需要加上 = 。因为 any 语义不对,没有意思,必须=any 才有 里面的任意一个 的语义;

    some 则是失败产物 any 的补救,因为 !=any 语义是一点都不,这和它设计的初衷,不是其中一个,背道而驰了,设计者,才想起来,我曹,any , 在否定时态中,含义完全相悖,赶紧设计一个 some 来救场 ;(some 完全等价于 any

    all 则是全部的意思,条件必须全部匹配上,才行。!=all 则是全部不匹配 ;

    anysomeall ,使用都需要搭配 = !=


    行子查询

    **案例:查询整个学生中,年龄最大并且身高是最高的

    • 朴素的做法:

      mysql> select * from student where 
          -> age = (select max(age) from student)
          -> and
          -> height = (select max(height) from student);
      

      这里统计函数,不是用在where后面,而是用在了标量子查询里面,因此是可以使用的;

    • 行子查询:

      只有构建 行元素 ,才算上是行子查询;

      mysql> select * from student where 
          -> -- 构建行元素
          -> (age,height) 
          -> =  (select max(age),max(height) from student);
      

    表子查询

    将子查询的结果当做二维表使用;这个有别于前面的几个,返回的结果都不能称为是二维表 ;

    案例:找出某个班中身高最高的人;

    -- 先让学生表按照身高降序排序
    select * from student order by height desc ;
    
    -- 然后按照班级分组 
    select * from student group by c_id ;
    
    -- 合并在一起,就是我们需要的
    select * from (select * from student group by c_id) as student order by height desc ;
    
    

    我们可以看到,该子查询,发生在 from 之后,将得到的结果作为from的数据源,所以,表子查询,也称 from子查询 ;


    Exists查询

    用来判断条件是否满足,可以理解为 if

    exists 接在 where 之后使用 ;

    exists 的返回值只要 0 1 两种 ;

    案例:如果班级表有数据,则查出学生表的数据(好无厘头的需求。。);

    select * from student where 
    -- 判断班级表是否存在
    exists(select * from calss) ;
    
  • 相关阅读:
    仿函数(functor)
    七周七语言
    面向签名编程
    git checkout简介
    .gitkeep常用写法
    PhpStorm terminal无法输入命令的解决方法
    原 在windows上创建文件名以“.”开头的文件
    cmd 里面运行git提示“不是内部或外部命令,也不是可运行的程序”的解决办法
    .gitkeep
    git/github运用
  • 原文地址:https://www.cnblogs.com/young-youth/p/11665634.html
Copyright © 2011-2022 走看看