超经典的20道SQL题目(附加解题思路)
Posted 是小叶的呢.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了超经典的20道SQL题目(附加解题思路)相关的知识,希望对你有一定的参考价值。
最近学了SQL的内容,老师也给我们发了练习题,感觉在做题的过程中得到了提高,所以将题目和我自己的答案分享一下,希望对大家有所帮助。我使用的是SQL Server 2014 Management Studio。
---学生表
create table student(
sno varchar(10) primary key, --学号
sname varchar(20), --姓名
sage numeric(2), --年龄
ssex varchar(5) --性别
);
----教师表
create table teacher(
tno varchar(10) primary key, ---教师编号
tname varchar(20) ---教师姓名
);
----课程表
create table course(
cno varchar(10), ---课程号
cname varchar(20), --课程名
tno varchar(20), --教师编号
constraint pk_course primary key (cno,tno)
);
---成绩表
create table sc(
sno varchar(10), ---学号
cno varchar(10), ---课程号
score numeric(4,2), ---学生成绩
constraint pk_sc primary key (sno,cno)
);
/*******初始化学生表的数据******/
insert into student values ('s001','张三',23,'男');
insert into student values ('s002','李四',23,'男');
insert into student values ('s003','吴鹏',25,'男');
insert into student values ('s004','琴沁',20,'女');
insert into student values ('s005','王丽',20,'女');
insert into student values ('s006','李波',21,'男');
insert into student values ('s007','刘玉',21,'男');
insert into student values ('s008','萧蓉',21,'女');
insert into student values ('s009','陈萧晓',23,'女');
insert into student values ('s010','陈美',22,'女');
/******************初始化教师表***********************/
insert into teacher values ('t001', '刘阳');
insert into teacher values ('t002', '谌燕');
insert into teacher values ('t003', '胡明星');
/***************初始化课程表****************************/
insert into course values ('c001','J2SE','t002');
insert into course values ('c002','Java Web','t002');
insert into course values ('c003','SSH','t001');
insert into course values ('c004','Oracle','t001');
insert into course values ('c005','SQL SERVER 2005','t003');
insert into course values ('c006','C#','t003');
insert into course values ('c007','javascript','t002');
insert into course values ('c008','DIV+CSS','t001');
insert into course values ('c009','php','t003');
insert into course values ('c010','EJB3.0','t002');
/***************初始化成绩表***********************/
insert into sc values ('s001','c001',78.9);
insert into sc values ('s002','c001',80.9);
insert into sc values ('s003','c001',81.9);
insert into sc values ('s004','c001',60.9);
insert into sc values ('s001','c002',82.9);
insert into sc values ('s002','c002',72.9);
insert into sc values ('s003','c002',81.9);
insert into sc values ('s001','c003','59');
1、 查询“c001”课程比“c002”课程成绩高的所有学生的学号;
解题思路:我需要查询的数据都在同一个表里面,所以这里我使用的是自连接
select a.sno from dbo.sc a
inner join dbo.sc b
on a.sno=b.sno
where a.cno='c001' and b.cno='c002'
and a.score>b.score
2、 查询平均成绩大于60 分的同学的学号和平均成绩;
解题思路: 这里使用了聚合函数求平均值avg
select sno,avg(score) from dbo.sc
group by sno
having avg(score)>60
3、查询所有同学的学号、姓名、选课数、总成绩;
解题思路:使用了聚合函数sum求和、count个数,以及左连接来查询出所有同学的信息
select xs.sno,sname,sum(score),count(cno)from dbo.student xs
left join dbo.sc cj
on xs.sno=cj.sno
group by xs.sno,sname
4、 查询姓“刘”的老师的个数;
解题思路:这里使用了like模糊查询,通配符百分比( % ):任何零个或多个字符的字符串
select count(tname)from dbo.teacher
where tname like'刘%'
5、 查询没学过“谌燕”老师课的同学的学号、姓名;
解题思路:这里我使用了嵌套子查询来查询没学过‘谌燕’老师的课,‘没学过’用not in,所以这里学生表要用 not in
select sno,sname from dbo.student
where sno not in(
select sno from dbo.sc
where cno in(
select cno from dbo.teacher
where tname='谌燕'
))
6、 查询学过“c001”并且也学过编号“c002”课程的同学的学号、姓名;
解题思路:使用了子查询和自连接,以及使用and查找满足两个条件的行
select sno,sname from dbo.student
where sno in(
select a.sno from dbo.sc a
inner join dbo.sc b
on a.sno=b.sno
where a.cno='c001' and b.cno='c002'
)
7、 查询学过“谌燕”老师所教的所有课的同学的学号、姓名;
解题思路:跟上面的第五题差不多,只是把‘没学过’not in 改成‘学过’ in
select sno,sname from dbo.student
where sno in(
select sno from dbo.sc
where cno in(
select cno from dbo.teacher
where tname='谌燕'
))
8、查询所有课程成绩小于60 分的同学的学号、姓名;
解题思路:使用了两个内连接和where条件查询子句
select xs.sno sname from dbo.student xs
inner join dbo.sc cj
on xs.sno=cj.sno
inner join dbo.course kc
on kc.cno=cj.cno
where cj.score<60
9、 查询没有学全所有课的同学的学号、姓名;
解题思路:使用子查询
select*from dbo.student
where sno not in (
select sno from dbo.sc
)
10、 查询至少有一门课与学号为“s001”的同学所学相同的同学的学号和姓名;
解题思路:使用嵌套子查询和where子句
select*from dbo.student
where sno in(
select sno from dbo.sc
where cno in(
select cno from dbo.student
where sno='s001'
)
)
11、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
解题思路:使用聚合函数 min最小值 max最大值
select cno 课程ID,max(score)最高分,min(score)最低分
from dbo.sc
group by cno
12、查询每门课程被选修的学生数
解题思路:使用聚合函数count个数
select cno ,count(*) from dbo.sc
group by cno
13、查询出只选修了一门课程的全部学生的学号和姓名
解题思路:这里只需要查询出只选修一门课的学生,首先我使用了内连接,其次是使用having子句来根据指定的条件列表过滤分组
select xs.sno,xs.sname,count(cno) from dbo.student xs
inner join dbo.sc cj
on xs.sno=cj.sno
group by xs.sno,xs.sname
having count(cno)=1
14、1981 年出生的学生名单(注:Student 表中Sage 列的类型是numeric)
解题思路:getdate获取当前时间datediff是计算日期时间。它有三个值datepart/startdate/Enddate,第一个是规定了应在日期的哪一部分计算差额的参数;第二个是计算的开始日期;第三个是计算的终止日期
select*from dbo.student
where sage=datediff(yyyy,'1981',getdate())
15、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列
解题思路:使用聚合函数,其次是asc升序和desc降序
select cno,avg(score)from dbo.sc
group by cno
order by avg(score) asc,cno desc
16、查询平均成绩大于85 的所有学生的学号、姓名和平均成绩
解题思路:使用了内连接和聚合函数
select xs.sno,sname,avg(score)from dbo.student xs
inner join dbo.sc cj
on xs.sno=cj.sno
group by xs.sno,sname
having avg(score)>85
17、查询课程编号为c001 且课程成绩在80 分以上的学生的学号和姓名;
解题思路:使用了内连接,以及使用and查找满足两个条件的行
select xs.sno,sname,score from dbo.student xs
inner join dbo.sc cj
on xs.sno=cj.sno
where cno='c001' and score>80
18、查询两门以上不及格课程的同学的学号及其平均成绩
解题思路:这里查询两门不及格的学生,使用where子句直接小于60,再通过having来判断是否大于1
select sno, avg(score) from dbo.sc
where score<60
group by sno
having count(*)>1
19、检索“c004”课程分数小于60,按分数降序排列的同学学号
解题思路:直接使用and来满足where查询出课程号为c004和分数小于60
select sno from dbo.sc
where cno='c004'
and score<60
order by score desc
20、删除“s002”同学的“c001”课程的成绩
delete from dbo.sc
where sno='s002' and cno='c001'
以上是关于超经典的20道SQL题目(附加解题思路)的主要内容,如果未能解决你的问题,请参考以下文章