今天我们要介绍的是子查询
  子查询大家应该都不陌生啦,在很多地方可以使用到的
  首先我们来总结一下SQL子查询可以用在哪些地方
  子查询的位置
Select <子查询> from <子查询> where <子查询>
 
 Insert table (columns) <子查询>
 
  Delete table from <子查询> where <子查询>
 
Update table from <子查询> where <子查询>
 
    那么,你们知道子查询的关键字有哪些吗?
  IN
  EXISTS
  对,就这两个,是不是很简单呢
 
  可是,要把子查询用好,可不是一件这么容易的事情
 
  今天我们来介绍子查询IN
  IN 关键字使您得以选择与列表中的任意一个值匹配的行
  太抽象了是吗,我们还是来看看实例吧:
  这是一个数据模型
 
  请用SQL来实现以下问题
  1.显示成绩全部及格的学生名单
 
  2.显示各班总成绩最好的学生名单
 
  3.显示各班各课目成绩前3位学生的成绩
 
  第一题应该很简单,其实有很多种写法
  首先,如何得到及格的学生呢?
  select 学号 from 成绩 where 成绩>=60
  然后,这样只能得到学号呀,所以,我们需要:
  select * from 学生 where 学号 in (select 学号 from 成绩 where 成绩>=60)
  换一个写法可不可以呢?
  select * from 学生 where 学号 not in (select 学号 from 成绩 where 成绩<60)
  当然可以,想想哪种效率高,班上是及格的学生多还是不及格的学生多呢?
  如果及格的学生多,那么select 学号 from 成绩 where 成绩<60,是不是返回的数据量更小呢?当然效率就高一些!
 
  第二题,显示各班总成绩最好的学生名单
  我们先把问题简单化,得到某一个班成绩最好的学生
  select max(成绩) from 成绩 where 班级=XX
  这个容易吧!
  各班成绩最好的呢?
  select 学号 from 成绩 a where 成绩=(select max(成绩) from 成绩 where 班级=a.班级
  把成绩表A与子查询通过班级关联,用成绩做条件,搞定!
  学生名单
  select * from 学生 where 学号 in (
       select 学号 from 成绩 a where 成绩=(select max(成绩) from 成绩 where 班级=a.班级)
)
  也不复杂吧
 
  第三题,显示各班各课目成绩前3位学生的成绩
  跟第二题有点象吧,可是,大家注意,第二题只取每个班的第一名,我们可以用MAX,这里,似乎用不了了吧….
  怎么办呢
  其实很简单,在第二题中,我们的成绩是用=,而这题中,我们的成绩用IN不就可以了吗?
  select * from 学生 where 学号 in
       select 学号 from 成绩 a where 成绩 in (select top 3 成绩 from 成绩 where 班级=a.班级 order by 成绩 desc)
)
  不过,有没有发现小漏洞呢,如果我有两个第三名的成绩一样,会返回几条记录呢,留给大家想想吧:)
 
  关于使用子查询IN,给大家一个小忠告:子查询适合外结果集大,子查询结果集小的情况,千万不能滥用子查询IN,您一定要保证子查询所返回的结果集尽量的小,哪怕你的SQL返回记录数只有1条,如果你使用到了子查询,而你的子查询返回10000条,那速度会受到很大影响呢,那天你的SQLSERVER当机了,可千万不要来找我麻烦呀,哈哈
  还有,其实第二题中的子查询与外面的表进行关联XX=外表.XX,一般情况下,我们是不太赞同这样使用的,同时会存在性能问题
  好了, 子查询IN就介绍到这里了,是不是很有趣呢?
 

相关文章:sql多表查询:不等连接 sql多表查询:Where 和 On的秘密

posted on 2009-07-30 17:30  LanrenXuan  阅读(4285)  评论(0编辑  收藏  举报