技术交流QQ群:1027579432,欢迎你的加入!

子查询

  • 子查询:查询操作是在某个查询结果上进行的,一条select语句内部包含了另外一条select语句。
  • 分类:按结果和位置进行分类。
  • 按结果分类:根据子查询得到的数据进行分类,具体可以分成以下几类:
    • 标量子查询:子查询得到的结果是一行一列,出现的位置在where之后;
    • 列子查询:子查询得到的结果是一列多行,出现的位置在where之后;
    • 行子查询:子查询得到的结果是一行多列,出现的位置在where之后;
    • 表子查询: 子查询得到的结果是多行多列,出现的位置在from之后;
  • 按位置分类:根据子查询select语句在外部查询select语句中出现的位置进行分类,分为:
    • from子查询:子查询出现在from之后;
    • where子查询:子查询出现在where之后;
    • exists子查询: 子查询出现在exists之后;

标量子查询

  • 需求:知道班级名为PM3.1,想要获取该班的全部学生。
  • 思路:
    • 1.确定数据源,学生表
      SELECT * FROM student where c_id = ?;
    • 2.获取班级ID,通过班级名称来确定
      SELECT id FROM class where grade = "PM3.1";
    • 3.标量子查询
      SELECT * FROM student where c_id = (SELECT id FROM class where grade = "PM3.1");

列子查询

  • 需求:查询所有在读班级(学生表中存在的班级)的学生。
  • 思路:
    • 1.确定数据源,学生表
      SELECT * FROM student where c_id = ?;
    • 2.确定全部有效的班级ID
      SELECT * FROM class;
    • 3.列子查询
      SELECT * FROM student where c_id in (SELECT * FROM class);
  • 在列子查询的结果是一列多行时,需要使用in作为条件进行匹配;此外,还有三个类似的条件,分别是any、some、all
    • any等价于in,表示其中一个
    • any等价于some,而any和some用于否定时却有区别
    • all表示等于全部
  • 注意:上面的三个关键字使用时,都要搭配=来使用!any、some、all在用于否定时,其会将null值排除。

行子查询

  • 需求:查询年龄最大且身高最高的学生
  • 思路:
    • 1.确定数据源,学生表
      SELECT * FROM student where age = ? and height = ?;
    • 2.确定最大年龄和最大身高
      SELECT max(age), max(height) FROM student;
    • 3.行子查询
      SELECT * FROM student where (age, height) = (SELECT max(age), max(height) FROM student);

表子查询

  • 需求:找出每个班身高最高的学生
  • 思路:
    • 1.确定数据源,将学生身高按照降序排列
      SELECT * FROM student order by height DESC;
    • 2.从每个班中选第一个学生
      SELECT * FROM student group by c_id;
    • 3.表子查询
      SELECT * FROM (SELECT * FROM student order by height DESC) as student group by c_id;

exists子查询

  • exists:表示是否存在的意思,因此exists子查询就是用来判断某些条件是否满足(跨表),exists是接在where之后,其返回的结果为1或0,满足条件为1,反之为0.
  • 需求:班级存在条件下,查询所有的学生
  • 思路:
    • 1.确定数据源
      SELECT * FROM student WHERE ?;
    • 2.确定条件是否满足
      exists(SELECT * FROM class);
    • 3.exists子查询
      SELECT * FROM student where exists(SELECT * FROM class);