SELECT查询语句SELECT—FROM—WHERE句型
在关系代数中最常用的式子是下列表达式:
πA1,…,An(σF(R1×…×Rm))
这里R1、…、Rm为关系,F是公式,A1、…、An为属性。
针对上述表达式,SQL为此设计了SELECT—FROM—WHERE句型:
SELECT A1,…,An FROM R1,…,Rm WHERE F
这个句型是从关系代数表达式演变来的,但WHERE子句中的条件表达式F要比关系代数中公式更灵活。
SELECT句型使用实例例3.8 教学数据中有三个基本表(关系):
S(S#,SNAME,AGE,SEX)
SC(S#,C#,GRADE)
C(C#,CNAME,TEACHER)
下面用SELECT查询语句表达每个查询。
① 检索学习课程号为C2的学生学号与成绩。
SELECT S#,GRADE FROM SC WHERE C#=‘C2’
② 检索学习课程号为C2的学生学号与姓名。
第一种写法:
SELECT S.S#,SNAME FROM S,SC WHERE S.S#=SC.S# AND C#='C2'
第二种写法:
SELECT S#,SNAME FROM S
WHERE S# IN (SELECT S# FROM SC
WHERE C#='C2')
查询涉及多个基本表时用嵌套结构逐次求解层次分明,具有结构程序设计特点。并且嵌套查询的执行效率也比连接查询的笛卡儿积效率高。在嵌套查询中,IN是经常用到的谓词,其结构为“元组IN(集合)”,表示元组在集合内。
第三种写法:
SELECT S#,SNAME FROM S
WHERE EXISTS(SELECT * FROM SC
WHERE SC.S#=S.S# AND C#='C2')
EXISTS通常用于嵌套查询,它不采用等号,也不是IN关键字,它直接与嵌套查询相关联。采用的嵌套查询之间的连接不是列的关系,而是表的关系。
③ 检索选修课程名为MATHS的学生学号与姓名。
第一种写法:
SELECT S.S#,SNAME FROM S,SC,C
WHERE S.S#=SC.S# AND SC.C#=C.C# AND CNAME=‘MATHS’
第二种写法:
SELECT S#,SNAME FROM S
WHERE S# IN (
SELECT S# FROM SC
WHERE C# IN (SELECT C# FROM C
WHERE CNAME='MATHS'))
④ 检索选修课程号为C2或C4的学生学号。
SELECT S# FROM SC WHERE C#='C2' OR C#='C4'
⑤ 检索至少选修课程号为C2和C4的学生学号。
SELECT X.S# FROM SC AS X,SC AS Y
WHERE X.S#=Y.S# AND X.C#='C2' AND Y.C#='C4‘
同一个基本表SC在一层中出现了两次,为加以区别,引入别名X和Y。书写时,保留字AS在语句中可省略,可直接写成“SC X,SC Y”(改名操作)
⑥ 检索不学C2课程的学生姓名与年龄。
第一种写法:
SELECT SNAME,AGE FROM S
WHERE S# NOT IN (SELECT S# FROM SC WHERE C#='C2')
第二种写法:
SELECT SNAME,AGE FROM S
WHERE NOT EXISTS (SELECT * FROM SC WHERE SC.S#=S.S# AND C#='C2')
⑦ 检索学习全部课程的学生姓名。(在表S中找学生,在C中不存在一门课程,这个学生没有学)
SELECT SNAME FROM S
WHERE NOT EXISTS
(SELECT * FROM C
WHERE NOT EXISTS
(SELECT * FROM SC
WHERE SC.S#=S.S# AND SC.C#=C.C#))
⑧ 检索所学课程包含学生S3所学课程的学号。
语义改成如下双重否定形式:
在SC表中找一个学生(S#)
不存在S3学的一门课(C#)
该学生没有学
SELECT DISTINCT S#
FROM SC X
WHERE NOT EXISTS
(SELECT *
FROM SC Y
WHERE Y.S#=‘S3'
AND NOT EXISTS
(SELECT *
FROM SC Z
WHERE Z.S#=X.S# AND Z.C#=Y.C#))
SELECT语句的图示形式例3.9 对于例3.8中的第二个查询语句的图示形式如下所述。
cFO
N齹9epenc0<