万金流
初次使用博客园,目前感觉还不错。 不知不觉用了4年零4个月了,越来越喜欢博客园。

如题。一个不算复杂的东西,书上说的太绕了,不能忍。

准备数据,这里有三张表(偷懒,各种编号都是整数)。

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的例子),按道理来说,效率会很差。但现在各种数据库对这种情况,都有优化。所以在使用的时候,应该尽量避免;避不开,也不用去纠结效率问题。

 

posted on 2023-03-20 16:33  万金流  阅读(517)  评论(0编辑  收藏  举报