SQL经典50题
时间:2021-07-01 10:21:17
帮助过:6人阅读
.查询"
01"课程比"
02"课程成绩高的学生的信息及课程分数
select *
from
(select t1.sid,class1,class2
from
(select sid,score
as class1
from sc
where cid
=‘01‘ )
as t1
join
(select sid,score
as class2
from sc
where cid
=‘02‘)
as t2
on t1.sid
=t2.sid
and t1.class1
>t2.class2
)r
left join student
on r.sid
=student.sid
;
1.1 查询存在"
01 "课程但可能不存在"
02 "课程的情况(不存在时显示为
null )
select *
from
(select * from sc
where cid
=‘01‘)t1
left join
(select * from sc
where cid
=‘02‘)t2
on t1.sid
=t2.sid
;
1.2 查询同时存在01和02课程的情况
select *
from
(select * from sc
where cid
=‘01‘
)t1
join (
select * from sc
where cid
=‘02‘
)t2
on t1.sid
=t2.sid
;
1.3 查询选择了02课程但没有01课程的情况
select * from sc
where cid
=‘02‘ and sid
not in (
select sid
from sc
where cid
=‘01‘)
;
2.查询平均成绩大于等于
60 分的同学的学生编号和学生姓名和平均成绩
select t1.sid,t1.meanscore,student.sname
from
(select sid,
avg(score)
as meanscore
from sc
group by sid
having avg(score)
>=60
)t1
left join student
on t1.sid
=student.sid
;
3.查询在 SC 表存在成绩的学生信息
select distinct student.
*
from sc
join student
on sc.sid
=student.sid
;
4.查询所有同学的学生编号、学生姓名、选课总数、所有课程的成绩总和
select r.
*,student.sname
from
(select sid,
count(
distinct cid)
as qcourse,
sum(score)
as sumscore
from sc
group by sid
)r
left join student
on r.sid
=student.sid
;
5.查询「李」姓老师的数量
select count(
*)
from teacher
where tname
like (
‘李%‘)
;
6.查询学过「张三」老师授课的同学的信息
select student.
*
from
(select * from teacher
where tname
= ‘张三‘
)t1
left join course
on t1.tid
=course.tid
left join sc
on course.cid
=sc.cid
left join student
on sc.sid
=student.sid
;
@7.查询没有学全所有课程的同学的信息
select student.
*,qcourse
from
(select sid,
count(
distinct cid)
as qcourse
from sc
group by sid
having count(
distinct cid)
<(
select count(
distinct cid)
from course)
)
left join student
on sc.sid
=student.sid
;
@8.查询至少有一门课与学号为"
01 "的同学所学相同的同学的信息
select student.
*
from sc
join student
on sc.sid
=student.sid
where sc.cid
in (
select cid
from sc
where sid
=‘01‘
)
and sc.sid
!=‘01‘
group by sc.sid
;
@9.查询和"
01 "号的同学学习的课程完全相同的其他同学的信息
10.查询没学过"张三"老师讲授的任一门课程的学生姓名
select sname
from student
where sid
not in(
select sid
from sc
left join course
on sc.cid
=course.cid
left join teacher
on course.tid
=teacher.tid
where teacher.tname
!=‘张三‘)
;
11.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select t1.
*,student.sname
from
(select sid,
avg(score)
as meanscore
from sc
where sid
in (
select sid,
count(
distinct cid)
from sc
where score
<60
group by sid
having count(
distinct cid)
>=2)
)t1
left join student
on t1.sid
=student.sid
;
12.检索"
01 "课程分数小于
60,按分数降序排列的学生信息
select student.
*,t1.score
from
(select *
from sc
where cid
=‘01‘
and score
<60
)t1
left join student
on t1.sid
=student.sid
order by t1.score
desc
;
13.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
select sc.
*,t1.meanscore
from sc
left join
(select sid,
avg(score)
as meanscore
from sc
group by cid
)t1
on sc.sid
=t1.sid
order by t1.meanscore
;
14.查询各科成绩最高分、最低分和平均分,以如下形式显示:
课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
及格为>=60,中等为:
70-80,优良为:
80-90,优秀为:
>=90
要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序
排列
select cid
as ‘课程 ID‘,
count(sid)
as ‘课程人数‘,
max(score)
as ‘最高分‘,
min(score)
as ‘最低分‘,
avg(score)
as ‘平均分‘,
cast(
cast sum(及格)
as double)
/(
cast count(sid)
as double)
as ‘及格率‘,
SUM(中等)
/ COUNT(sid)
AS ‘中等率‘,
SUM(优良)
/ COUNT(sid)
AS ‘优良率‘,
SUM(优秀)
/ COUNT(sid)
AS ‘优秀率‘
from
(select *,
case when score
>=60 then 1 else 0 end as ‘及格‘,
case when score
>=70 and score
<80 then 1 else 0 end as ‘中等 ‘,
case when score
>=80 and score
<90 then 1 else 0 end as ‘优良‘,
case when score
>=90 then 1 else 0 end as ‘优秀‘
from sc
)a
group by cid
order by count(sid)
desc,cid
;
@15.按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺
select a.
*,
count(a.score)
as ‘排名‘
from sc a
left join sc b
on a.sid
=b.sid
and a.score
< b.score
group by a.cid,a.sid,a.score
order by a.cid
;
--用sc中的score和自己进行对比,来计算“比当前分数高的分数有几个”。
@15.
1 按各科成绩进行行排序,并显示排名, Score 重复时合并名次
select a.
*,
count(b.score)
+1 as ‘排名‘
from sc a
left join sc b
on a.sid
=b.sid
and a.score
< b.score
group by a.cid,a.sid,a.score
order by a.cid
;
@16.查询学生的总成绩,并进行排名,总分重复时保留名次空缺
select a.
*,
@rank:
=@rank+1 as rank
from
(select sid,
sum(score)
from sc
group by sid
order by sum(score)
desc
)a,
(select @rank:
=0
)b
;
17. 统计各科成绩各分数段人数:课程编号,课程名称,
[100-85],
[85-70],
[70-60],
[60-0] 及所占百分比
select a.
*,course.cname
from
(select cid,
sum(
case when score
>=85 and score
<=100 then 1 else 0 end )
/count(
distinct sid)
as ‘[100-85]‘,
sum(
case when score
>=70 and score
<85 then 1 else 0 end )
/count(
distinct sid)
as ‘[85-75]‘,
sum(
case when score
>=60 and score
<70 then 1 else 0 end )
/count(
distinct sid)
as ‘[70-60]‘,
sum(
case when score
<60 then 1 else 0 end )
/count(
distinct sid)
as ‘[60-0]‘
from sc
group by cid
)a
left join course
on a.cid
=course.cid
;
18.查询各科成绩前三名的记录
select a.
*,
count(b.score)
+1 as ranking
from sc
as a
left join sc
as b
on a.cid
=b.cid
and a.score
<b.score
group by a.cid,a.sid
having ranking
<=3
order by a.cid,ranking
--having where不能使用别名,group by order by中可以使用别名
--
select *
from
(select *,row_number()
over(partition
by cid
order by score
desc)
as ranking
from sc)
where ranking
>=3
;
19.查询每门课程被选修的学生数
select cid,
count(
distinct sid)
as num
from sc
group by cid
;
20.查询出只选修两门课程的学生学号和姓名
select sc.sid,student.sname
from sc
left join student
on sc.sid
=student.sid
group by sc.cid
having count(cid)
=2
;
21. 查询男生、女生人数
select count(
case when ssex
=‘男‘ then sid
else null end)
as ‘男生人数‘,
count(
case when ssex
=‘女‘ then sid
else null end)
as ‘女生人数‘
from student
;
22. 查询名字中含有「风」字的学生信息
select *
from student
where sname
like ‘%风%‘
;
23查询同名同性学生名单,并统计同名人数
select sname,
count(ssex)
from student
group by sname
having count(ssex)
>1
;
24.查询
1990 年出生的学生名单
select *
from student
where year(sage)
like‘1990%‘
;
25.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
select cid,
avg(score)
as meanscore
from sc
group by cid
order by meanscore
desc,cid
;
26.查询平均成绩大于等于
85 的所有学生的学号、姓名和平均成绩
select a.sid,student.sname,a.meanscore
from
(select sid,
avg(score)
as meanscore
from sc
group by sid
having avg(score)
>=85
)a
left join student
on a.sid
=student.sid
;
27.查询课程名称为「数学」,且分数低于
60 的学生姓名和分数
select student.sname,b.socre
from
(select cid
from course
where cname
=‘数学‘
)a
left join
(select *
from sc
where score
<60
)b
on a.cid
=b.cid
left join student
on b.sid
=student.sid
;
28. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
select sname,sc.cid,sc.score
from sc
join student
on sc.sid
=student.sid
;
29.查询任何一门课程成绩在
70 分以上的姓名、课程名称和分数
select sname,sc.cid,sc.score
from sc
join student
on sc.sid
=student.sid
where sc.score
>70
;
30.查询不及格的课程
select distinct cid
from sc
where score
<60
;
31.查询课程编号为
01 且课程成绩在
80 分以上的学生的学号和姓名
select sc.sid,sname
from
(select *
from sc
where cid
=‘01‘and score
>80
)a
left join student
on a.sid
=student.sid
;
32.求每门课程的学生人数
select cid,
count(sid)
as cnt
from sc
group by cid
;
33.成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
select student.
*,sc.score
from
(select tid
from teacher
where tname
=‘张三‘
)a
left join course
on a.tid
=course.tid
left join sc
on course.cid
=sc.cid
left join student
on sc.sid
=student.sid
order by sc.score
desc
limit 1
;
34.成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生
35.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
select distinct a.
*
from sc
as a
join sc
as b
on a.score
=b.score
and a.cid
!=b.cid
;
36. 查询每门成绩最好的前两名
select *
from
(select *,
row_number()over(partition
by cid
order by score
desc)
as ranking
)
where ranking
<=2
;
--方法2自交
select *
from sc
where (
select count(
*)
from sc
as a
where sc.cid
=a.cid
and sc.score
<a.score
)<2
order by cid ,sc.score
desc
;
37. 统计每门课程的学生选修人数(超过
5 人的课程才统计)
select cid,
count(sid)
from sc
group by sc
having count(sid)
>5
;
38.检索至少选修两门课程的学生学号
select cid,
count(sid)
from sc
group by sc
having count(sid)
>2
;
39.查询选修了全部课程的学生信息
select student.
*
from
(select sid
from sc
where cid
=(
select count(
distinct cid)
from course
)
)a
left join student
on a.sid
=student.sid
;
40.查询各学生的年龄,只按年份来算
select sname,
year(now())
-year(age)
as ‘年级‘
from student
;
41. 按照出生日期来算,当前月日
< 出生年月的月日则,年龄减一
select sname,
case when (date_format(now(),
‘%m-%d‘)
-date_format(sage,
‘%m-%d‘)
<0
then year(now())
-year(sage)
+1
else year(now())
-year(sage)
end as ‘年龄‘
from student
;
--date_format转化为时间戳,利用时间戳求差值
42.查询本周过生日的学生
select *
from student
where weekofyear(date_format(now(),
‘%y%m%d‘))
=
weekofyear(date_format(sage,‘%y%m%d‘)
-date_format(sage,
‘%y‘)
*10000+date_format(now(),
‘%y‘)
*10000)
;
--出生日期的年份去掉,得到月份和日期,再拼接上当前的年份
--weekofyear函数是计算出当前日期所在周数
43. 查询下周过生日的学生
select *
from student
where weekofyear(date_format(now(),
‘%y%m%d‘))
+1
=
weekofyear(date_format(sage,‘%y%m%d‘)
-date_format(sage,
‘%y‘)
*10000+date_format(now(),
‘%y‘)
*10000)
;
44.查询本月过生日的学生
select sname
from student
where month(sage)
=month