实验内容
1、 多表查询
(1)等值与非等值连接
(2)自身连接
(3)复合条件连接
(4)外连接
2、 集合查询
交 并 差
3、 嵌套查询
(1)带有IN谓词的子查询 sno in() in 里面对应sno
(2)带有比较运算符的子查询
(3)带有any或all的子查询 ???
(4)带有exists或not exists的子查询(连接查询 实现全称量词)
实验过程
例1:工程项目j2使用的各种零件的名称和数量(数量要求和)
select Pname,sum(qty)as 数量 from spj,p
where p.pno=spj.pno
and jno='j2'
group by pname
/*红螺丝刀和蓝螺丝刀属于同一种零件*/
例2:上海厂商提供的所有零件号码(用in实现)
select distinct pno
from spj
where sno in(
select sno from s
where city='上海'
)
例3:没有使用天津生产的零件的工程号(用in 或not exists实现)
select jno
from j ---不能在spj中查询
where not exists(
select *
from spj,s where s.sno=spj.sno and j.jno=spj.jno and city='天津' --注意要和j表连接
)
select distinct jno
from j ---不能在spj中查询
where jno not in( --不相关子查询
select distinct jno
from spj,s where s.sno=spj.sno and city='天津'
)例4:查询课程的间接先行课及学分
----查询课程的间接先行课及课程的学分
select c1.cno 课程,c2.cno 先行课的先行课,c1.Ccredit 课程的学分
from Course c1,Course c2
where c1.cpno=c2.cno
----查询课程的间接先行课及间接先行课的学分
select c1.cno 课程,c2.cno 先行课的先行课,c3.Ccredit 先行课的先行课的学分
from Course c1,Course c2,Course c3
where c1.cpno=c2.cno and c2.cpno=c3.cno
例5:查询选修了“数据库”课程的学生姓名和成绩
select Sname,grade
from student,course,sc
where student.sno=sc.sno
and course.cno=sc.cno
and course.Cname='数据库'
例6:查询选修了数据库的同学的课程平均分和学号
select sno,avg(grade) 选修了数据库的同学的课程平均分
from sc
where sno in(
select sno
from sc,course
where sc.cno=course.cno and cname='数据库'
)
group by sno
例7:查询选修数据库同学中数据库的最高分及学生姓名
--例7:查询选修数据库同学中数据库的最高分及学生姓名
/*
select sname,max(grade)
from student,sc
where student.sno=sc.sno and student.sno in(
select sno --子查询找出所有选修数据库的同学的学号
from sc,course
where sc.cno=course.cno and cname='数据库')
group by sname
*/错误错误错误错误错误错误
select sname,grade
from student,sc
where student.sno=sc.sno and grade>=all(
select grade --子查询找出所有选修数据库的同学的数据库的成绩
from sc,course
where sc.cno=course.cno and cname='数据库')
例8:查询选修全部课程的学生学号
Select sno --------------------------假的 查询哪个学生至少有一门课没有选修
From student
Where not exists
(select * ------------查询某学生对应一门课程他没有选修
From course
Where not exists
(select* -----某个学生选修的所有课程
From sc
Where sno=student.sno
And cno=course.cno))
附:
课后习题
4.针对上题中建立的四个表试用SQL语言完成第二章习题5中的查询:
(1) 求供应工程J1零件的供应商号码SNO:
SELECT DIST SNO FROM SPJ WHERE JNO=’J1’
(2) 求供应工程J1零件P1的供应商号码SNO:
SELECT DIST SNO FROM SPJ WHERE JNO='J1' AND PNO='P1'
(3) 求供应工程J1零件为红色的供应商号码SNO:
SELECT SNO FROM SPJ,P WHERE JNO='J1' AND SPJ.PNO=P.PNO AND COLOR='红'
(4) 求没有使用天津供应商生产的红色零件的工程号JNO:
SELECT DIST JNO FROM SPJ WHERE JNO NOT IN (SELE JNO FROM SPJ,P,S WHERE S.CITY='天津' AND COLOR='红' AND S.SNO=SPJ.SNO AND P.PNO=SPJ.PNO)。
(5) 求至少用了供应商S1所供应的全部零件的工程号JNO。??????
由于VFP不允许子查询嵌套太深,将查询分为两步
A、查询S1供应商供应的零件号
SELECT DIST PNO FROM SPJ WHERE SNO='S1'结果是(P1,P2)
B、查询哪一个工程既使用P1零件又使用P2零件。
SELECT JNO FROM SPJ WHERE PNO='P1'
AND JNO IN (SELECT JNO FROM SPJ WHERE PNO='P2')
5.针对习题3中的四个表试用SQL语言完成以下各项操作:
(1)找出所有供应商的姓名和所在城市。
SELECT SNAME,CITY FROM S
(2)找出所有零件的名称、颜色、重量。
SELECT PNAME,COLOR,WEIGHT FROM P
(3)找出使用供应商S1所供应零件的工程号码。
SELECT DIST JNO FROM SPJ WHERE SNO='S1'
(4)找出工程项目J2使用的各种零件的名称及其数量。
SELECT PNAME,QTY FROM SPJ,P
WHERE P.PNO=SPJ.PNO AND SPJ.JNO='J2'
(5)找出上海厂商供应的所有零件号码。
SELECT PNO FROM SPJ,S WHERE S.SNO=SPJ.SNO AND CITY='上海'
(6)出使用上海产的零件的工程名称。
SELECT JNAME FROM SPJ,S,J
WHERE S.SNO=SPJ.SNO AND S.CITY='上海' AND J.JNO=SPJ.JNO
(7)找出没有使用天津产的零件的工程号码。
注意: SELECT DISP JNO FROM SPJ WHERE JNO NOT IN (SELECT DIST JNO FROM SPJ,S WHERE S.SNO=SPJ.SNO AND S.CITY='天津') 适用于JNO是唯一或不唯一的情况.
注意: SELECT DIST JNO FROM SPJ,S WHERE S.SNO=SPJ.SNO AND S.CITY<>'天津'适用于JNO是唯一的情况
(8)把全部红色零件的颜色改成蓝色。
UPDATE P SET COLOR='蓝' WHERE COLOR='红'
(9)由S5供给J4的零件P6改为由S3供应。
UPDATE SPJ SET SNO='S3' WHERE SNO='S5' AND JNO='J4' AND PNO='P6'
(10)从供应商关系中删除供应商号是S2的记录,并从供应情况关系中删除相应的记录。
A、DELETE FROM S WHERE SNO=’S2’
B、DELETE FROM SPJ WHERE SNO=‘S2’
(11)请将(S2,J6,P4,200)插入供应情况关系。
INSERT INTO SPJ VALUES(‘S2’,‘J6’,‘P4’,200)
注 :
注 查询选修了所有课程的学生姓名的貌似比较容易理解的 算法
select sname from student
where sno in (
select sno from sc
group by sno
having count(*) =
( select count(*) from course)
)