SQL经典50题

一、导入SQL数据表

1.学生表

1
2
3
4
5
6
7
8
9
10
11
12
13
create table Student(SId varchar(10),Sname varchar(10),Sage datetime,Ssex varchar(10));
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-05-20' , '男');
insert into Student values('04' , '李云' , '1990-08-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-03-01' , '女');
insert into Student values('07' , '郑竹' , '1989-07-01' , '女');
insert into Student values('09' , '张三' , '2017-12-20' , '女');
insert into Student values('10' , '李四' , '2017-12-25' , '女');
insert into Student values('11' , '李四' , '2017-12-30' , '女');
insert into Student values('12' , '赵六' , '2017-01-01' , '女');
insert into Student values('13' , '孙七' , '2018-01-01' , '女');

2.课程表

1
2
3
4
create table Course(CId varchar(10),Cname nvarchar(10),TId varchar(10));
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03');

3.教师表

1
2
3
4
create table Teacher(TId varchar(10),Tname varchar(10));
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');

4.成绩表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
create table SC(SId varchar(10),CId varchar(10),score decimal(18,1));
insert into SC values('01' , '01' , 80);
insert into SC values('01' , '02' , 90);
insert into SC values('01' , '03' , 99);
insert into SC values('02' , '01' , 70);
insert into SC values('02' , '02' , 60);
insert into SC values('02' , '03' , 80);
insert into SC values('03' , '01' , 80);
insert into SC values('03' , '02' , 80);
insert into SC values('03' , '03' , 80);
insert into SC values('04' , '01' , 50);
insert into SC values('04' , '02' , 30);
insert into SC values('04' , '03' , 20);
insert into SC values('05' , '01' , 76);
insert into SC values('05' , '02' , 87);
insert into SC values('06' , '01' , 31);
insert into SC values('06' , '03' , 34);
insert into SC values('07' , '02' , 89);
insert into SC values('07' , '03' , 98);

二、SQL函数和优化

记录一次SQL函数和优化的问题

三、题目与题解

1.查询” 01 “课程比” 02 “课程成绩高的学生的信息及课程分数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT
student.*,
sc1.CId AS 01课程,
sc2.score AS 01课程分数,
sc2.CId AS 02课程,
sc2.score AS 02课程分数
FROM
student,
sc sc1,
sc sc2
WHERE
student.SId = sc1.Sid
AND student.SId = sc2.Sid
AND sc1.CId = '01'
AND sc2.CId = '02'
AND sc1.score > sc2.score

2.查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT
student.SId,
Sname,
AVG( score )
FROM
student,
sc
WHERE
student.SId = sc.SId
GROUP BY
sc.SId
HAVING
AVG( score ) > 60

3.查询在 SC 表存在成绩的学生信息

1
2
3
4
SELECT st.*
FROM student st, sc
where st.SId = sc.SId
GROUP BY sid

4.查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )

1
2
3
4
5
6
7
8
9
10
SELECT
student.sid,
sname,
count( sc.cid ) AS 选课数,
SUM( score ) AS 总成绩
FROM
student
LEFT JOIN sc ON student.SId = sc.SId
GROUP BY
student.SId

5.查询姓“张”的老师个数

1
2
3
4
5
6
SELECT
COUNT( tid ) as 张姓老师
FROM
teacher
WHERE
Tname LIKE '张%'

6.查询学过张三老师课的学生的学号和姓名

1
2
3
4
5
6
7
8
9
10
11
SELECT
student.Sid,
Sname
FROM
student,
sc
WHERE
student.SId = sc.SId
AND Cid IN ( SELECT Cid FROM teacher, course WHERE teacher.TId = course.TId AND Tname = '张三' )
GROUP BY
Sid

7.查询没有学全所有课程的同学的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT
st.*
FROM
student st
WHERE
st.SId NOT IN (
SELECT
sid
FROM
sc
GROUP BY
sid
HAVING
count( cid ) = ( SELECT count( cid ) FROM course )
)

8.查询至少有一门课与学号为” 01 “的同学所学相同的同学的信息

1
2
3
4
SELECT st.*
FROM student st, sc
WHERE st.SId = sc.SId AND cid in (SELECT cid FROM sc where sid = '01') AND sc.SId != '01'
GROUP BY sid

9. 查询和” 01 “号的同学学习的课程 完全相同的其他同学的信息

1
2
3
4
5
SELECT st.*
FROM student st, sc
WHERE st.SId = sc.SId AND cid in (SELECT cid FROM sc WHERE sid = '01') AND sc.SId != '01'
GROUP BY sid
HAVING COUNT(cid) = (SELECT COUNT(cid) FROM sc WHERE SId = '01')

10. 查询没学过”张三”老师讲授的任一门课程的学生姓名

1
2
3
4
5
6
7
SELECT sname
FROM student
WHERE Sname not in (
SELECT Sname
FROM student st, sc, course c, teacher t
WHERE st.SId = sc.SId AND sc.CId = c.CId AND c.TId = t.TId AND tname = '张三'
)

11. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩

1
2
3
4
5
SELECT st.SId, Sname, AVG(score)
FROM student st, sc
WHERE st.SId = sc.SId
GROUP BY sc.SId
HAVING SUM(score < 60) >= 2

12. 检索” 01 “课程分数小于 60,按分数降序排列的学生信息

1
2
3
4
SELECT st.*, score
FROM student st, sc
WHERE st.SId = sc.SId AND CId = '01' AND score < 60
ORDER BY score DESC

13.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

1
2
3
4
SELECT st.SId, st.Sname, Cname, score, AVG(score) OVER (PARTITION BY SId) 平均成绩
FROM student st, sc, course
WHERE st.SId = sc.SId AND course.CId = sc.CId
ORDER BY 平均成绩 DESC

14. 查询各科成绩最高分、最低分和平均分

1
2
3
4
SELECT Cname, MAX(score), MIN(score), AVG(score)
FROM course, sc
WHERE course.CId = sc.CId
GROUP BY sc.CId

15.以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率;及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SELECT
sc.CId 课程ID,
Cname 课程名,
MAX( score ) 最高分,
MIN( score ) 最低分,
AVG( score ) 平均分,
SUM( score >= 60 )/ COUNT( score ) 及格率,
SUM(CASE WHEN score BETWEEN 70 AND 80 THEN 1 ELSE 0 END)/ COUNT( score ) 中等率,
SUM(CASE WHEN score BETWEEN 80 AND 90 THEN 1 ELSE 0 END)/ COUNT( score ) 优良率,
SUM( score >= 90 )/ COUNT( score ) 优秀率
FROM
course,
sc
WHERE
course.CId = sc.CId
GROUP BY
sc.CId

16.按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺

1
2
3
4
5
6
SELECT
cid,
rank() over ( PARTITION BY cid ORDER BY score DESC ) 排名,
score
FROM
sc

17.按各科成绩进行排序,并显示排名,Score 重复时合并名次

1
2
3
4
5
6
SELECT
cid,
dense_rank() over ( PARTITION BY cid ORDER BY score DESC ) 排名,
score
FROM
sc
  • 使用rank(),1,2,2,4,4,6
  • 使用dense_rank(),1,2,2,3,3,4

18.要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列

1
2
3
4
SELECT CId, count(SId)
FROM sc
GROUP BY CId
ORDER BY 2 DESC, 1 ASC

19.查询学生的总成绩,并进行排名,总分重复时保留名次空缺

1
2
3
4
5
6
7
8
SELECT
SId,
SUM( score ) 总分,
rank() over (ORDER BY sum( score ) DESC) 排名
FROM
sc
GROUP BY
sid

20.查询学生的总成绩,并进行排名,总分重复时不保留名次空缺

1
2
3
4
5
6
7
8
SELECT
SId,
SUM( score ) 总分,
dense_rank() over (ORDER BY sum( score ) DESC) 排名
FROM
sc
GROUP BY
sid

21.统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比

1
2
3
4
5
6
7
8
9
10
SELECT
cid,
sum( CASE WHEN score BETWEEN 85 AND 100 THEN 1 ELSE 0 END )* 1.0 / count( sid ) '85-100',
sum( CASE WHEN score BETWEEN 70 AND 85 THEN 1 ELSE 0 END )* 1.0 / count( sid ) '70-85',
sum( CASE WHEN score BETWEEN 60 AND 70 THEN 1 ELSE 0 END )* 1.0 / count( sid ) '60-70',
sum( CASE WHEN score BETWEEN 85 AND 100 THEN 1 ELSE 0 END )* 1.0 / count( sid ) '0-60'
FROM
sc
GROUP BY
cid

22.查询各科成绩前三名的记录

1
2
3
4
5
6
SELECT
*
FROM
( SELECT cid, sid, score, ROW_NUMBER() over ( PARTITION BY Cid ORDER BY score ) AS pm FROM sc ) t
WHERE
pm <= 3

23. 查询每门课程被选修的学生数

1
2
3
4
5
6
7
SELECT
cid,
count( sid )
FROM
sc
GROUP BY
cid

24.查询出只选修两门课程的学生学号和姓名

1
2
3
4
5
SELECT st.SId, Sname
FROM student st, sc
WHERE st.SId = sc.SId
GROUP BY SId
HAVING COUNT(CId) = 2

25. 查询男生,女生人数

1
2
3
SELECT Ssex, COUNT(SId)
FROM student st
GROUP BY Ssex

26.查询名字中含有「风」字的学生信息

1
2
3
4
5
6
SELECT
*
FROM
student
WHERE
sname LIKE '%风%'

27.查询同名同性学生名单,并统计同名人数

1
2
3
4
5
6
7
SELECT
Sname,
COUNT( SId )
FROM
student
GROUP BY
Sname

28.查询 1990 年出生的学生名单

1
2
3
4
5
6
7
SELECT
Sname,
Sage
FROM
student
WHERE
Sage BETWEEN '1990-01-01' AND '1991-01-01'

29.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列

1
2
3
4
SELECT cid, AVG(score)
FROM sc
GROUP BY CId
ORDER BY 2 DESC, 1

30.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩

1
2
3
4
5
SELECT st.SId, Sname, AVG(score) avg_score
FROM student st, sc
WHERE st.SId = sc.SId
GROUP BY SId
HAVING avg_score >= 85

31.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩

1
2
3
SELECT Sname, Cname, score
FROM student st, sc, course c
WHERE st.SId = sc.SId AND Cname = '数学' AND c.CId = sc.CId AND score < 60

32.查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)

1
2
3
4
5
6
7
SELECT
st.sid,
st.sname,
sc.*
FROM
student st
LEFT JOIN sc ON st.sid = sc.sid

33.查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数

1
2
3
SELECT Sname, Cname, score
FROM student st, sc, course c
WHERE st.SId = sc.SId AND c.CId = sc.CId AND score > 70

34.查询不及格的成绩

1
2
3
SELECT st.SId, Sname, Cname, score
FROM student st, sc, course c
WHERE st.SId = sc.SId AND c.CId = sc.CId AND score < 60

35.查询程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT
st.SId,
Sname,
Cname,
score
FROM
student st,
sc,
course c
WHERE
st.SId = sc.SId
AND c.CId = sc.CId
AND c.CId = '01'
AND score >= 80

36.求每门课程的学生人数

1
2
3
4
5
6
7
SELECT
sc.cid,
count( sc.sid )
FROM
sc
GROUP BY
sc.cid

37.成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

1
2
3
SELECT st.*, c.CId, MAX(score)
FROM student st, sc, teacher t, course c
WHERE t.Tname = '张三' AND c.TId = t.TId AND sc.CId = c.CId AND st.SId = sc.SId

38.成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

1
2
3
4
5
SELECT st.*, c.CId, score
FROM student st, sc, teacher t, course c
WHERE t.Tname = '张三' AND c.TId = t.TId AND sc.CId = c.CId AND st.SId = sc.SId AND score = (SELECT MAX(score)
FROM student st, sc, teacher t, course c
WHERE t.Tname = '张三' AND c.TId = t.TId AND sc.CId = c.CId AND st.SId = sc.SId)

39.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

1
2
3
4
5
6
7
8
9
10
11
SELECT st.SId, Sname, CId, score
FROM student st, sc
WHERE st.SId = sc.SId
GROUP BY SId
HAVING MAX(score) = MIN(score)

select sc.* from sc,
(select sid,cid,score from sc
group by sid
having count(distinct cid) > count(distinct score)) t1
where sc.sid = t1.sid

40.查询每门功成绩最好的前两名

1
2
3
4
5
6
SELECT
*
FROM
( SELECT Cid, SId, ROW_NUMBER() OVER ( PARTITION BY Cid ORDER BY score DESC ) AS pm, score FROM sc ) t
WHERE
pm <=2

41.统计每门课程的学生选修人数(超过 5 人的课程才统计)

1
2
3
4
SELECT Cid, COUNT(SId) c
FROM sc
GROUP BY CId
HAVING c > 5

42.检索至少选修两门课程的学生学号

1
2
3
4
SELECT Sid, COUNT(CId) c
FROM sc
GROUP BY SId
HAVING c > 2

43.查询选修了全部课程的学生信息

1
2
3
4
5
SELECT st.*
FROM sc, student st, course c
WHERE sc.SId = st.SId
GROUP BY SId
HAVING COUNT(DISTINCT sc.CId) = COUNT(DISTINCT c.CId)

44.查询各学生的年龄

1
2
3
4
5
SELECT
sname,
TIMESTAMPDIFF(YEAR,sage,CURDATE())
FROM
student

45.查询本周过生日的同学

1
2
3
4
5
6
7
SELECT
*
FROM
student
WHERE
WEEKOFYEAR( student.Sage )= WEEKOFYEAR(
CURRENT_DATE ())

46.查询下周过生日的同学(没考虑跨年)

1
2
3
4
5
6
7
SELECT
*
FROM
student
WHERE
WEEKOFYEAR( student.Sage )= WEEKOFYEAR(
CURRENT_DATE ())+ 1

47.查询本月过生日的同学

1
2
3
4
5
6
7
SELECT
*
FROM
student
WHERE
MONTH ( student.Sage )= MONTH (
CURRENT_DATE ())

48.查询下月过生日的同学

1
2
3
4
5
6
7
SELECT
*
FROM
student
WHERE
CASE WHEN MONTH (sage)= 12 THEN MONTH (sage)= 1 ELSE MONTH (sage)=(CURDATE())+ 1 END;


SQL经典50题
https://blog.gutaicheng.top/2022/11/05/SQL50题/
作者
GuTaicheng
发布于
2022年11月5日
许可协议