sql多表查询之三:子查询IN

关于使用子查询IN,给你们一个小忠告:子查询IN适合外结果集大,子查询结果集小的状况,千万不能滥用子查询IN,您必定要保证子查询所返回的结果集尽可能的小,哪怕你的SQL返回记录数只有1条,若是你使用到了子查询IN,而你的子查询返回10000条,那速度会受到很大影响呢

你们都领会过使用不等链接进行库存计算的神妙了吧,有没有应用到本身的学习与工做中去呢?今天咱们上第三盆菜,子查询,有什么建议或意见也欢迎你们多多留言讨论啦!sql

什么?你尚未看到不等链接,那么点点这里吧 sql多表查询之二:不等链接
今天咱们要介绍的是子查询
子查询你们应该都不陌生啦,在不少地方可使用到的
首先咱们来总结一下 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 成绩 a where 成绩 in(select top 3 成绩 from 成绩 where 班级=a.班级 and 课目=a.课目order by 成绩.成绩 desc)
不过,有没有发现小漏洞呢,若是我有两个第三名的成绩同样,会返回几条记录呢,留给你们想一想吧:)
 
关于使用子查询IN,给你们一个小忠告:子查询适合外结果集大,子查询结果集小的状况,千万不能滥用子查询IN,您必定要保证子查询所返回的结果集尽可能的小,哪怕你的SQL返回记录数只有1条,若是你使用到了子查询,而你的子查询返回10000条,那速度会受到很大影响呢,那天你的SQLSERVER当机了,可千万不要来找我麻烦呀,哈哈
还有,其实第二题中的子查询与外面的表进行关联XX=外表.XX,通常状况下,咱们是不太赞同这样使用的,同时会存在性能问题
那么,会不会更好的解决方案呢?下期四夕将介绍子查询中应用面更广的 EXISTS,静请关注哦!
相关文章
相关标签/搜索