如题。一个不算复杂的东西,书上说的太绕了,不能忍。
准备数据,这里有三张表(偷懒,各种编号都是整数)。
t1是学生基本情况表,重要的字段是学号和姓名。
t2是课程表,包括课程号和课程名。
t3是选课表,包括前两个表的编号。
内容如下:
t1:
t2:语文数学英语
t3:
所谓条件子查询,即以一个查询的结果,作为另一个查询中参照的条件。
先来考虑一个查询,正常情况下可能有哪些结果:
1、一条结果;2、多条结果。
拿它来做参照条件,那么
- 对一条结果来说:
如果足够简单(只有一列),那就当成一个参照值处理即可。
例:zs同学(假设不重名)选了哪些编号的课程
select cid from t3 where xh=(select xh from t1 where xm='zs');
如果结果有好几列,也可以用组合【即:(,)】的方式,当成单个值来处理。
例:列出学号为1,选了课程编号为1的课程的同学的姓名和课程名称(例子不考虑查询效率,下同)
select xm,cmc from t1,t2 where (xh,cid) = (select * from t3 where xh=1 and cid=1);
- 如果行数不止一行,那么就需要确定一下,你是要满足所有行(all),还是只满足其中一行(any)即可。
例:选了编号为1的课程的同学,都叫什么名字?(满足其中一行)
select xm from t1 where xh=any(select xh from t3 where cid=1);
例:列出所有选了课的同学的姓名和课程名称(组合方式满足其中一行)
select xm,cmc from t1,t2 where (xh,cid) = any(select * from t3);
“=any”这种写法,还可以简写成“in”
例:选修了编号为1的课程的同学,入学成绩分别是多少?
select rxcj from t1 where xh in (select xh from t3 where cid=1);
例:比1号和2号都大的同学,叫什么名字?(满足所有行的条件)
select xm from t1 where sr<all(select sr from t1 where xh=1 or xh=2);
注:some和any作用相同,记住一个就行。
对于条件子查询,exists可以简单检测结果存在,前面可以加“not”表示不存在。
例:输出没有选课的学生姓名。
select xm from t1 where not exists(select * from t3 where t1.xh=t3.xh);
注意:1、考虑到查询效率,在任何时候,都应尽量避免使用笛卡尔积。2、对于在条件子查询内使用外面字段作为查询条件的情况(如上面exists的例子),按道理来说,效率会很差。但现在各种数据库对这种情况,都有优化。所以在使用的时候,应该尽量避免;避不开,也不用去纠结效率问题。