本文基于数据库作业(写都写了,就上传一下),由于初学数据库,所写查询语句可能不太规范(有的查询效率未必最好),后续有时间在更新!!!
1)department 表(院系编号、院系名称),deptNo是主键。
create table department
(deptNo smallint,
deptName varchar(50),
primary key(deptNo));
2)student表(学号、姓名、年龄、性别、院系),sno是主键,deptNo是外键。
create table student
(
sno char(8),
sname char(8),
sage smallint ,
ssex char(2),
deptNo smallint,
primary key(sno),
foreign key(deptNo) references department(deptNo)
);
3)course表(课程号、课程名、先修课、学分、院系编号),cno是主键。
create table student
(
sno char(8),
sname char(8),
sage smallint,
ssex char(2) ,
deptNo smallint ,
primary key(sno),
foreign key(deptNo) references department(deptNo)
);
4)选课表(学号、课程号、成绩),学号和课程号联合做主键。
create table sc
(
sno char(8),
cno char(4),
grade int,
primary key(sno,cno)
);
二、 创建索引
- 创建Student的姓名字段的索引
create unique index Stu_name on student(sname);
2.创建SC表的课程号升序、成绩降序索引
create unique index sc_no on cs(cno asc,grade desc);
三、 SQL查询
- 检索计算机系的学生。
select *
from
student t1,department t2
where t1.deptNo=t2.deptNo and t2.deptName='CS'; -- 由于只知道计算机系而不知道院系代码,故此题不能单表查询
- 检索年龄大于20岁的女学生的学号和姓名。
select sno,sname
from
student
where sage>20 and ssex='女';
- 检索姓名以王打头的所有学生的姓名和年龄。
select sname,sage
from
student
where sname like '王%';
- 查询姓名为‘X国X’同学。
select *
from
student
where sname like '_国_';
- 在SC中检索成绩为空值的学生学号和课程号。
select sno,cno
from sc
where grade is NULL;
- 输出c01课程的成绩单,要求成绩按从高到低排序。
select *
from
sc
where cno='c01' order by grade desc;
- 求选修C04课程的学生的平均分。
select avg(grade)
from
sc
where cno='C04';
- 每个学生选修的课程门数。
select sno,count(cno)
from
sc
group by sno;
- 检索至少选修两门课程的学生学号。
select sno
from
sc
group by sno
having count(cno)>=2;
- 求每个学生平均成绩。
select sno,avg(grade)
from
sc
group by sno;
- 统计每门课程的学生选修人数(超过3人的课程才统计)。查询结果按人数降序排列,若人数相同,按课程号升序排列。
select cno,count(sno)
from
sc
group by cno
having count(sno)>3
order by count(sno) desc,cno asc;
多表联合查询
- 检索每个学生的总学分,输出学号、姓名、院系和总学分,按院系排序。
select t1.sno,t1.sname,t1.deptNo,sum(grade)
from
student t1,sc t2
where t1.sno=t2.sno
group by t1.sno
order by t1.deptNo
- 检索计算机系所开课程的课程号和课程名。
select cno,cname
from
course t1, department t2
where t1.deptNo=t2.deptNo and t2.deptName='cs'
- 检索缺考2门以上的学生姓名。
select sname
from
student t1,(select sno,count(*) count_nu
from
sc
where grade is null
group by sno) t2
where t1.sno=t2.sno and t2.count_nu>2
- 检索选修C语言且成绩不及格的计算机系的学生的姓名与学号。
select sname,t1.sno
from
student t1,sc t2,course t3,department t4
where t1.sno=t2.sno and t2.cno=t3.cno and t3.cname='c语言' and t4.deptName='cs' and grade<60;
- 求计算机系所开课程的每门课程的学生平均成绩,按平均成绩从高到低排序输出。
select cno,avg(grade) avg_g
from
sc
where cno in (select cno
from
course t1,department t2
where deptName='cs' and t1.deptNo=t2.deptNo)
group by cno
order by avg_g desc
- 检索所有学生及其所学课程的信息,即使没有选课,也要列出学生的信息。
select *
from
student t1 left outer join sc t2 on(t1.sno=t2.sno);
- 查询选修3门以上课程且平均成绩大于80的学生的学号
select sno
from
sc
GROUP BY sno
HAVING COUNT(*)>3 and avg(grade)>80;
- 查询选修3门以上课程且平均成绩大于80的学生的学号、姓名、所在系名。
select sno,sname,deptName
from
student t1,department t2
where t1.sno in
(select sno
from
sc
GROUP BY sno
HAVING COUNT(*)>3 and avg(grade)>80)
and t1.deptNo=t2.deptNo;
- 检索王丽同学所学课程的课程号和课程名。
select t3.cno,t3.cname
from
sc t1,student t2,course t3
where t2.sname='王丽' and t1.sno=t2.sno and t1.cno=t3.cno;
嵌套查询
- 检索选修‘c01’课程的女学生的姓名
select sname
from
student
where ssex='女' and sno=(select sno from sc where cno='c01')
- 检索学号比王丽同学小,而年龄比她大的学生姓名
select sname
from
student t1,
(select sage,sno
from
student
where sname='王丽') t2
where t1.sage>t2.sage and t1.sno<t2.sno;
- 检索s01同学不学的课程的课程号。
select cno
from
course
where cno not in
(select cno
from
sc
where sno='s01')
- 检索王丽同学不学的课程的课程号。(in和exists两种方法)
select cno
from
course
where cno not in
(select cno
from
sc t1, student t2
where t1.sno=t2.sno and t2.sname='王丽')
select cno
from
course
where not exists
(select *
from
sc t1, student t2
where t1.sno=t2.sno and t2.sname='王丽')
- 检索至少选修计算机系所开课程2门以上的女学生姓名
select sname
from
student stu,
(select sno,count(*) count_co
from
sc
where cno in (
select cno
from
course t1, department t2
where t1.deptNo=t2.deptNo and t2.deptName='cs'
)
group by sno) sun
where sun.count_co>2 and stu.sno=sun.sno
- 查询没有选修c02,c03,c04的同学的学号。
select sno
from
sc
where sno not in(select sno
from
sc
where cno in(2,3,4))
- 查询既选修了‘数据库’又选修了‘操作系统’的学生的姓名及学号。
select sname,t1.sno
from
student t1,(select sno from sc where cno='数据库') t2,(select sno from sc where cno='操作系统') t3
where t1.sno=t2.sno and t2.sno=t3.sno;
- 查询即没有选修‘数据库’又没有选修‘操作系统’的学生的姓名及学号。(使用子查询和集合运算两种方法实现)
select t1.sno,sname
from
student t1,sc t2,course t3
where t1.sno=t2.sno and t2.cno=t3.cno and t3.cname='数据库'
intersect
select t1.sno,sname
from
student t1,sc t2,course t3
where t1.sno=t2.sno and t2.cno=t3.cno and t3.cname='操作系统' -- 由于mysql不支持intersect操作,故该操作无效
select t1.sno,sname
from
student t1,sc t2,course t3
where t1.sno=t2.sno and t2.cno=t3.cno and t3.cname='数据库'
and t1.sno in
(select t1.sno
from
student t1,sc t2,course t3
where t1.sno=t2.sno and t2.cno=t3.cno and t3.cname='操作系统')
- 检索选修了全部课程的学生的学号与姓名。
select sno, sname
from
student
where not exists
(select *
from
course
where not exists
(select *
from
sc
where sno=student.sno
and cno=course.cno))
- 检索选修计算机系所开全部课程的学生的学号与姓名。
select sno,sname
from
student
where not exists
(select *
from
course tc,(select cno
from
course t1, department t2
where t1.deptNo=t2.deptNo and t2.deptName='cs') ts
where tc.cno=ts.cno and not exists
(select *
from
sc
where sno=student.sno
and cno=tc.cno))