SQL 子查询可以分为相关子查询 与 非相关子查询。
假设Books表如下:
类编号  图书名         出版社               价格
--------------------------------------------------------
2 c#高级应用 圣通出版 23.00
2 Jsp开发应用 机械出版社 45.00
3 高等数学 济南出版社 25.00
3 疯狂英语 清华大学出版社 32.00

一、嵌套子查询的执行不依赖与外部的查询。
执行过程:
(1)执行子查询,其结果不被显示,而是传递给外部查询,作为外部查询的条件使用,子查询中不能有order by分组语句。
(2)执行外部查询,并显示整个结果。

嵌套子查询一般可以分为:返回单值的子查询 和 返回一个列表的子查询 ,
下面举例说明:
1.返回单值: --查询所有价格高于平均价格的图书名,作者,出版社和价格。 SElECT 图书名,作者,出版社,价格
FROM Books
WHERE 价格 >
(
SELECT AVG(价格)
FROM Books
)
GO
2.返回值列表--查询所有借阅图书的读者信息
SElECT *
FROM Readers
WHERE 读者编号 IN
(
SELECT 读者编号
FROM [Borrow History]
)
GO  

二、相关子查询的执行依赖于外部查询。多数情况下是子查询的WHERE子句中引用了外部查询的表
执行过程:
(1)从外层查询中取出一个元组,将元组相关列的值传给内层查询。
(2)执行内层查询,得到子查询操作的值。
(3)外查询根据子查询返回的结果或结果集得到满足条件的行。
(4)然后外层查询取出下一个元组重复做步骤1-3,直到外层的元组全部处理完毕。   
下面举例说明:
查询Booka表中大于该类图书价格平均值的图书信息

SElECT 图书名,出版社,类编号,价格
  SELECT FROM Books As a
WHERE 价格 >
(
SELECT AVG(价格)
FROM Books AS b
WHERE a.类编号=b.类编号
)
GO
与前面介绍过的子查询不同,相关子查询无法独立于外部查询而得到解决。该子查询需要一个“类编号”的值。而这个值是个变量,随SQLSever检索Books表中的不同行而改变。
下面详细说明该查询执行过程:
  先将Books表中的第一条记录的“类编号”的值“2”代入子查询中,子查询变为:
      SELECT AVG(价格)
       FROM Books AS b
     WHERE b.类编号=2
  子查询的结果为该类图书的平均价格,所以外部查询变为:
      SElECT 图书名,出版社,类编号,价格
       FROM Books As a
     WHERE 价格 > 34
如果WHERE条件为True,则第一条结果包括在结果集中,则否不包括。对Books表中的所有行运行相同的过程,最后形成的结果集及最后返回结果。

在嵌套中使用exists关键字[存在]
例:1:用嵌套work表和嵌套部门表,在嵌套work表中检索出姓名和职工号都在嵌套部门存在的职工资料 
     select * from 嵌套work a where exists (select * from 嵌套部门 b where a.姓名=b.姓名 and a.职工号=b.职工号)
   2:在work表检索出在部门表没有的职工
     select * from work where not exists (select * from 部门 where 部门.部门编号=work.部门编号)
     能否改成:select * from work where exists (select * from 部门 where 部门.部门编号<>work.部门编号) 是不能的,

在列清单中使用select
例:1:在work1表和部门表中检索出所有部门的部门名称和基本工资总和
    select 部门名称,(select sum(基本工资) from work1 b where a.部门编号=b.部门编号) from 部门 a
   2:检索各部门的职工人数
    select 部门编号,部门名称,(select count(职工号) from work1 a where a.部门编号=b.部门编号) as 人数 from 部门 b
   3:在商品表和销售表中查询每一职工的姓名,所属部门,销售总量                   
    select 姓名,所属部门,(select sum(销售量) from 商品销售 a where a.职工号=b.职工号) as 销售总量 from 嵌套部门 b

说明:都是相关子查询的特殊情况,外层的查询是内层查询的条件如:a.职工号=b.职工号,内层条件成立则得到的些行记录是并入外层查询的最终结果,否则不记录入最后结果

-------------------------------------------------------------------------------------------------------------------------------------------------------------

3:相关子查询(多值子查询)

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

查询中再查询,通常是以一个查询作为条件来供另一个查询使用
      例:有work表和部门表
         A:检索出在部门表中登记的所有部门的职工基本资料
           select * from work where 部门编号 in [not in](select 部门编号 from dbo.部门) 
         B:检索出在work表中每一个部门的最高基本工资的职工资料
           select * from work a where 基本工资=(select max(基本工资) from work b where a.部门名称=b.部门名称) 
           说明:由外查询提供一个部门名称给内查询,内查询利用这个部门名称找到该部门的最高基本工资,然后外查询根据基本工资判断是否等于最高工资,如果是的,则显示出来.
           相当于:select * from work,(select 部门名称,max(基本工资) as 基本工资 from work group by 部门名称 as t) where work.基本工资=t.基本工资 and work.部门名称=t.部门名称
         C:用嵌套work表和嵌套部门表,在嵌套work表中检索出姓名和职工号都在嵌套部门存在的职工资料 
           select * from 嵌套work where 职工号 in (select 职工号 from 嵌套部门) and 姓名 in (select 姓名 from 嵌套部门) [察看结果,分析原因] (错误,因为这两个in不是一对一
           改:select * from 嵌套work a,嵌套部门 b where a.职工号=b.职工号 and a.姓名=b.姓名 
           改:select * from 嵌套work where 职工号=(select 职工号 from 嵌套部门) and 姓名=(select 姓名 from 嵌套部门) [行吗?为什么,分析原因?] 不能后面的select得到的结果不是一个值而又跟在=后必然出错

在嵌套中使用exists关键字[存在]
例:1:用嵌套work表和嵌套部门表,在嵌套work表中检索出姓名和职工号都在嵌套部门存在的职工资料 
     select * from 嵌套work a where exists (select * from 嵌套部门 b where a.姓名=b.姓名 and a.职工号=b.职工号)
   2:在work表检索出在部门表没有的职工
     select * from work where not exists (select * from 部门 where 部门.部门编号=work.部门编号)
     能否改成:select * from work where exists (select * from 部门 where 部门.部门编号<>work.部门编号) 是不能的,

在列清单中使用select
例:1:在work1表和部门表中检索出所有部门的部门名称和基本工资总和
    select 部门名称,(select sum(基本工资) from work1 b where a.部门编号=b.部门编号) from 部门 a
   2:检索各部门的职工人数
    select 部门编号,部门名称,(select count(职工号) from work1 a where a.部门编号=b.部门编号) as 人数 from 部门 b
   3:在商品表和销售表中查询每一职工的姓名,所属部门,销售总量                   
    select 姓名,所属部门,(select sum(销售量) from 商品销售 a where a.职工号=b.职工号) as 销售总量 from 嵌套部门 b

说明:都是相关子查询的特殊情况,外层的查询是内层查询的条件如:a.职工号=b.职工号,内层条件成立则得到的些行记录是并入外层查询的最终结果,否则不记录入最后结果

许多查询都可以通过执行一次子查询并将得到的值代入外部查询的 WHERE 子句中进行计算。在包括相关子查询(也称为重复子查询)的查询中,子查询依靠外部查询获得值。这意味着子查询是重复执行的,为外部查询可能选择的每一行均执行一次。


												

SQL--相关子查询 与 非相关子查询的更多相关文章

  1. SQL简单嵌套查询与非嵌套查询的比较(MSSQL2005)

    某天的工作是修复某个项目的bug,接着就发现,其sql极其混乱,有非常多的left join和in操作,还有嵌套查询(只有一个表的嵌套查询).不知道看到过哪里的资料说,嵌套查询速度慢,于是我把全部嵌套 ...

  2. SQL Server调优系列基础篇 - 子查询运算总结

    前言 前面我们的几篇文章介绍了一系列关于运算符的介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符.有兴 ...

  3. SQL Server 调优系列基础篇 - 子查询运算总结

    前言 前面我们的几篇文章介绍了一系列关于运算符的介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符.有兴 ...

  4. SQL夯实基础(四):子查询及sql优化案例

    首先我们先明确一下sql语句的执行顺序,如下有前至后执行: (1)from  (2) on   (3) join  (4) where  (5)group by  (6) avg,sum...  (7 ...

  5. Thinkphp查询 1.查询方式 2.表达式查询 3.快捷查询 4.区间查询 5.组合查询 6.统计查询 7.动态查询 8.SQL 查询

    1.使用字符串作为条件查询 $user = M('User'); var_dump($user->where('id=1 AND user="蜡笔小新"')->sele ...

  6. SQL查询(笔记2——实体查询)

    SQL查询(笔记2——实体查询) 二.实体查询 如果查询返回了某个数据表的全部数据列,且该数据表有对应的持久化类映射,我们就把查询结果转换成实体查询.将查询结果转换成实体,可以使用SQLQuery提供 ...

  7. Entity Framework Code First+SQL Server,改变聚集索引,提高查询性能

    .net Entity Framework(调研的是Entity Framework 4.0) code first方式生成数据库时,不能修改数据库表的索引,而SQLServer默认会把数据表的主键设 ...

  8. SQL夯实基础(九)MySQL联接查询算法

    书接上文<SQL夯实基础(八):联接运算符算法归类>. 这里先解释下EXPLAIN 结果中,第一行出现的表就是驱动表(Important!). 对驱动表可以直接排序,对非驱动表(的字段排序 ...

  9. SQL 基础笔记(二):进阶查询

    本笔记整理自<SQL 基础教程>.<MySQL 必知必会>和网上资料.个人笔记不保证正确. 一.复杂查询 视图 将 SELECT 查询包装成一个虚拟表,该虚拟表就被称为视图.( ...

随机推荐

  1. ACM训练大纲

    1. 算法总结及推荐题目 1.1 C++ STL • STL容器: set, map, vector, priority_queue, queue, stack, deque, bitset• STL ...

  2. Zebra - zebra command to get printer error and warning status

    1 Flag2 Nibble 16-93 Nibble 8-44 Nibble 35 Nibble 26 Nibble 1

  3. Java中动态代理实现原理深究

    一.前言 笔者平时开发使用“动态代理”不多,最近在看设计模式的时候,“动态代理”又在面前晃了几次,所以这次想从源码的角度去分析动态代理的实现原理,以窥探其精妙~ 二.正文 2.1 静态代理  本文源码 ...

  4. 除了基本类型,其余类型基本上大部分new出来 java.sql 包下面要不需要new

    除了基本类型,其余类型基本上大部分new出来 java.sql 包下面要不需要new

  5. ES 1.7安装ik分词elasticsearch-analysis-ik-1.2.5

    IK简介 https://www.cnblogs.com/yjf512/p/4789239.html https://www.cnblogs.com/xing901022/p/5910139.html ...

  6. P4109 [HEOI2015]定价

    题目描述 在市场上有很多商品的定价类似于 999 元.4999 元.8999 元这样.它们和 1000 元.5000 元和 9000 元并没有什么本质区别,但是在心理学上会让人感觉便宜很多,因此也是商 ...

  7. 深入探讨Android异步精髓Handler

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 详解Android主流框架不可或缺的基石 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架 ...

  8. 【BZOJ 3669】 [Noi2014]魔法森林 LCT维护动态最小生成树

    这道题看题意是在求一个二维最小瓶颈路,唯一可行方案就是枚举一维在这一维满足的条件下使另一维最小,那么我们就把第一维排序利用A小的边在A大的情况下仍成立来动态加边维护最小生成树. #include &l ...

  9. 实际上ECMAScript中并没有对类的定义

    首先,我们用一个经典例子来简单阐述一下ECMAScript中的继承机制. 在几何学上,实质上几何形状只有两种,即椭圆形(是圆形的)和多边形(具有一定数量的边).圆是椭圆的一种,它只有一个焦点.三角形. ...

  10. Win10的WSL很好用呀

    WSL全名是Windows Subsystem for Linux,是win10版本号16xx之后推出的开发者功能,提供了如原生linux版的体验. 最近最新的win10春季版1803出来了,安装了看 ...