多表联查--05---SQL相关子查询与非相关子查询

子查询

子查询是嵌套在其他查询中的查询。子查询总是从内向外处理

注意:

  1. 在使用子查询时尽量把子查询分解为多行并且适当进行缩进,能极大的简化子查询的使用。
  2. 不能嵌套太多的子查询,这样会降低性能。
  3. 在WHERE子句中使用子查询,应该保证SELECT语句具有与WHERE子句中相同数目的列。
  4. 通常子查询将返回单个列并且与单个列进行匹配,但如果需要也可以使用多个列。

案例:

SELECT * FROM tab1 WHERE size IN (

SELECT size FROM tab2

)

子查询分类:

  • 相关子查询
  • 非相关子查询

非相关子查询

非相关子查询的执行: 不依赖与外部的查询

执行过程:

  1. 执行子查询,其结果不被显示,而是传递给外部查询,作为外部查询的条件使用。
  2. 执行外部查询,并显示整个结果。

非相关子查询一般可以分为:

  • 返回单值的子查询
  • 返回一个列表的子查询

案例:

多表联查--05---SQL相关子查询与非相关子查询_第1张图片

1.返回单值:

  • 查询所有价格高于平均价格的图书名,出版社和价格。
SELECT *
  FROM books
  WHERE 价格 >
  (
    SELECT AVG(价格)
    FROM books
  )

多表联查--05---SQL相关子查询与非相关子查询_第2张图片

2.返回值列表–查询所有借阅图书的读者信息

SElECT *
  FROM Readers
  WHERE 读者编号 IN
  (
    SELECT 读者编号
    FROM [Borrow History]
  )

相关子查询

相关子查询的执行依赖于外部查询
多数情况下是 子查询的WHERE 子句中引用了外部查询的表

执行过程:

  1. 从外层查询中取出一个元组,将元组相关列的值传给内层查询。
  2. 执行内层查询,得到子查询操作的值。
  3. 外查询根据子查询返回的结果或结果集得到满足条件的行。
  4. 然后外层查询取出下一个元组重复做步骤1-3,直到外层的元组全部处理完毕。

相关子查询中的 : 嵌套循环连接(Nested Loop Join)

多表联查--05---SQL相关子查询与非相关子查询_第3张图片
多表联查--05---SQL相关子查询与非相关子查询_第4张图片

案例:

多表联查--05---SQL相关子查询与非相关子查询_第5张图片
1.查询booka表中 同类编号中,该类图书价格低于平均值的图书信息

  SELECT * FROM books AS a
  WHERE 价格 <
  (
    SELECT AVG(价格)
    FROM books AS b
    WHERE a.类编号=b.类编号
  )

在这里插入图片描述
与前面介绍过的子查询不同,相关子查询无法独立于外部查询而得到解决。该子查询需要一个“类编号”的值。而这个值是个变量,随SQLSever检索Books表中的不同行而改变。

下面详细说明该查询执行过程:

第一步:

先将books表中的第一条记录的“类编号”的值“1”代入子查询中,子查询变为

SELECT AVG(价格) FROM books AS b WHERE b.类编号=1

多表联查--05---SQL相关子查询与非相关子查询_第6张图片

第二步:

子查询的结果为该类图书的平均价格34,所以外部查询条件为:

价格 < 34 AND 类编号=1

SELECT *  FROM books AS a WHERE 价格 < 34 AND 类编号=1;

多表联查--05---SQL相关子查询与非相关子查询_第7张图片

第三步:

将books表中的第一条记录的“类编号”的值“2”进行 上诉流程查询

总结

  • 非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。
  • 相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次

故非相关子查询 比 相关子查询效率高

你可能感兴趣的:(Mysql高级,sql,数据库,database)