SQL经典练习题+解析 「100%可以运行」

在这里插入图片描述

一、创建答题环境

二、经典题目

  1. 查询至少参加 01 和 02 两门课程考试的相关信息(查出 Sid 相关成绩 即可)

    -- 按照上面的描述我们只需要查 SC 这张表即可,查询出两门成绩即可
    select sc1.SId, sc1.score, sc2.score
    from (select * from sc where cid = '01') sc1
         inner join
     (select * from sc where cid = '02') sc2
    on sc1.sid = sc2.sid;
    
    SId score score
    01 80.0 90.0
    02 70.0 60.0
    03 80.0 80.0
    04 50.0 30.0
    05 76.0 87.0

    扩展:查询参加 01 02 03 三门课程的考试成绩和学生 id

    select sc1.SId, sc1.score as score1, sc2.score as score2, sc3.score as score2
    from (select * from sc where cid = '01') sc1
         join
     (select * from sc where cid = '02') sc2
         join
     (select * from sc where cid = '03') sc3
    on sc1.sid = sc2.sid and sc2.SId = sc3.SId;
    
    SId score1 score2 score2
    01 80.0 90.0 99.0
    02 70.0 60.0 80.0
    03 80.0 80.0 80.0
    04 50.0 30.0 20.0
  2. 查询参加 01 课程但是可能没有参加 02 课程的情况(不存在时显示null)

    -- 典型的连接查询,使用左连接即可
    select sc1.SId, sc1.score, sc2.score
    from (select * from sc where cid = '01') sc1
         left join
     (select * from sc where cid = '02') sc2
    on sc1.sid = sc2.sid;
    
    SId score score
    01 80.0 90.0
    02 70.0 60.0
    03 80.0 80.0
    04 50.0 30.0
    05 76.0 87.0
    06 31.0 NULL
  3. 查询可能没有参加 01 课程但是肯定参加 02 课程的情况(不存在时显示null)

    -- 使用右连接查询即可
    select sc2.SId, sc1.score, sc2.score
    from (select * from sc where cid = '01') sc1
     right join
     (select * from sc where cid = '02') sc2
    on sc1.sid = sc2.sid;
    
    SId score score
    01 80.0 90.0
    02 70.0 60.0
    03 80.0 80.0
    04 50.0 30.0
    05 76.0 87.0
    07 NULL 89.0
  4. 查询编号为的 01 课程比编号为 02 课程分数高的学生信息和课程分数

    -- 思路:首先要查出 01 和 02 课程的信息,然后使用学生 id 连接起来
    -- 这样就得到课程 01 比较 02 分数高的学生的 id 和相关的成绩
    select sc1.SId, sc1.score as sorce1, sc2.score as sorce2
    from (select SId, CId, score from SC where CId = '01') as sc1
         inner join
         (select SId, CId, score from SC where CId = '02') as sc2
         on sc1.SId = sc2.SId
    where sc1.score > sc2.score;
    
    SId sorce1 sorce2
    2 70.0 60.0
    4 50.0 30.0

    将上一步查询出的结果做子集使用 sid 与 student 表进行连接然后提取出相关信息即可

    在这里插入图片描述

    Id Sname Sage Ssex sorce1 sorce2
    2 钱电 1990-12-21 00:00:00 70.0 60.0
    4 李云 1990-12-06 00:00:00 50.0 30.0
  5. 查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩

    -- 连接以后使用 group by 分组即可
    select Sc.SId, s.Sname, avg(score) avg_s
    from SC
    inner join Student S
    on SC.SId = S.SId
    group by S.Sname, Sc.SId
    having avg_s > 60;
    
    Id Sname avg_s
    5 周梅 81.50000
    3 孙风 80.00000
    1 赵雷 89.66667
    7 郑竹 93.50000
    2 钱电 70.00000
  6. 查询在 SC 表存在成绩的学生信息

    -- 两边连接一起后使用 distinct 学生信息去重
    select distinct student.*
    from student
    join SC S
    on Student.SId = S.SId;
    
    SId Sname Sage Ssex
    01 赵雷 1990-01-01 00:00:00
    02 钱电 1990-12-21 00:00:00
    03 孙风 1990-12-20 00:00:00
    04 李云 1990-12-06 00:00:00
    05 周梅 1991-12-01 00:00:00
    06 吴兰 1992-01-01 00:00:00
    07 郑竹 1989-01-01 00:00:00
  7. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的成绩总和

    select Sname, count(SC.CId), sum(score)
    from SC
         join Student S on SC.SId = S.SId
    group by SC.SId, S.Sname;
    
    Sname count(SC.CId) sum(score)
    赵雷 3 269.0
    钱电 3 210.0
    孙风 3 240.0
    李云 3 100.0
    周梅 2 163.0
    吴兰 2 65.0
    郑竹 2 187.0
  8. 查询 李 姓老师的数量

    select count(1)
    from Teacher
    where Tname like '李%';
    
    count(1)
    1
  9. 查询 张三 老师授课的同学信息
    首先查出张三老师授课的信息 Cid Cname

    select CId, Cname
    from Course
         join Teacher T on Course.TId = T.TId
    where Tname = '张三';
    
    Id Cname
    2 数学

    再通过 SC 表查出学生信息

    select SId, Cname
    from SC join
    (select CId, Cname from Course
    join Teacher T
    on Course.TId = T.TId
    where Tname = '张三') as CS
    on CS.CId = SC.CId;
    
    Id Cname
    1 数学
    2 数学
    3 数学
    4 数学
    5 数学
    7 数学

    最后再通过 Student 查询相关的学生信息即可

    select *
    from Student
    where SId in (
    select SId
    from SC
    join (select CId, Cname
    from Course
    join Teacher T on Course.TId = T.TId
    where Tname = '张三') as cs
    on SC.CId = cs.CId);
    
    Id Sname Sage Ssex
    1 赵雷 1990-01-01 00:00:00
    2 钱电 1990-12-21 00:00:00
    3 孙风 1990-12-20 00:00:00
    4 李云 1990-12-06 00:00:00
    5 周梅 1991-12-01 00:00:00
    7 郑竹 1989-01-01 00:00:00

    解法二:inner join 将三张表连接起来然后查询

    在这里插入图片描述

  10. 查询没有参与所有考试的学生的信息
    首先从 SC 表中查询出每名同学参考考试的总数

    select SId, count(CId) from SC group by SC.SId;
    
    Id count(CId)
    1 3
    2 3
    3 3
    4 3
    5 2
    6 2
    7 2

    组合一下查询出参与了所有考试的学生的 Sid

    select SId from SC group by SC.SId
    having count(CId) = (select count(1) from Course);
    
    SId
    1
    2
    3
    4

    查询出的全是参加过所有考试的学生 Sid 现在只需要结合 Student 表 not in 即可

    SELECT Student.*
    FROM Student
    WHERE SId NOT IN
      (SELECT SId
       FROM SC
       GROUP BY SC.SId
    having count(CId) = (select count(1) from Course));
    
    Id Sname Sage Ssex
    5 周梅 1991-12-01 00:00:00
    6 吴兰 1992-01-01 00:00:00
    7 郑竹 1989-01-01 00:00:00
    9 张三 2017-12-20 00:00:00
    0 李四 2017-12-25 00:00:00
    1 李四 2012-06-06 00:00:00
    2 赵六 2013-06-13 00:00:00
    3 孙七 2014-06-01 00:00:00
  11. 查询至少一门参加的考试课程与学号为 01 的同学所参加的考试课程相同的同学信息
    这道题相对比较简单,首先查出 01 号同学参与的所有课程的 Cid

    select CId from SC where SId = 01;
    
    CId
    1
    2
    3

    接下来从 SC 表中查出参与考试与 01 号至少有一门相同的 Sid 使用 distinct 去重再使用 Student 表查出学生详细信息

    select * from Student where SId in (
    select distinct SId from SC
    where CId in (
    select CId from SC
    where SId = 01));
    
    Id Sname Sage Ssex
    1 赵雷 1990-01-01 00:00:00
    2 钱电 1990-12-21 00:00:00
    3 孙风 1990-12-20 00:00:00
    4 李云 1990-12-06 00:00:00
    5 周梅 1991-12-01 00:00:00
    6 吴兰 1992-01-01 00:00:00
    7 郑竹 1989-01-01 00:00:00
  12. 查询与 “01” 号的同学参加的考试课程完全相同的其他同学的信息
    首先从课程数量上过滤一部分学生,比如 01 参加 5 门考试,找一样的话优先考虑也参加 5 门的否则何谈相同

    SELECT Student.*
    FROM Student
    WHERE sid IN
      (SELECT sid
       FROM sc
       GROUP BY sid
       HAVING COUNT(sid) =
    (SELECT COUNT(cid) FROM sc WHERE sid = '01'));
    
    Id Sname Sage Ssex
    1 赵雷 1990-01-01 00:00:00
    2 钱电 1990-12-21 00:00:00
    3 孙风 1990-12-20 00:00:00
    4 李云 1990-12-06 00:00:00
    SELECT Student.*
    FROM Student
    WHERE sid IN
      (SELECT sid
       FROM sc
       GROUP BY sid
       HAVING COUNT(sid) =
              (SELECT COUNT(cid) FROM sc WHERE sid = '01')
      )
      AND sid NOT IN
      (SELECT sid
       FROM sc
       WHERE cid IN
       (SELECT DISTINCT cid FROM sc WHERE cid NOT IN
            (SELECT cid FROM sc WHERE sid = '01'))
       GROUP BY sid
      )
     AND sid NOT IN ('01');
    
  13. 查询没有参加 “张三” 老师讲授的任一门课程考试的学生的名字
    首先需要查询出张三老师授课 Cid 使用 Course 和 Teacher 表

    select cid
    from Teacher
    join Course C on Teacher.TId = C.TId
    where Tname = '张三';
    select *
    
    # from SC
    # left join (
    # select cid
    # from Teacher
    # join Course C on Teacher.TId = C.TId
    # where Tname = '张三') as SR
    # on SC.CId = SR.CId
    # where SR.cid is not null;;
    
    cid
    2

    将 SC 表和张三老师讲授表进行 左 连接

    select *
    from SC
    left join (
    select cid
    from Teacher
    join Course C on Teacher.TId = C.TId
    where Tname = '张三') as SR
    on SC.CId = SR.CId;
    
    SId CId score cid
    1 02 90.0 02
    2 02 60.0 02
    3 02 80.0 02
    4 02 30.0 02
    5 02 87.0 02
    7 02 89.0 02
    1 01 80.0 NULL
    1 03 99.0 NULL
    2 01 70.0 NULL
    2 03 80.0 NULL
    3 01 80.0 NULL
    3 03 80.0 NULL
    4 01 50.0 NULL
    4 03 20.0 NULL
    5 01 76.0 NULL
    6 01 31.0 NULL
    6 03 34.0 NULL
    7 03 98.0 NULL

    我们可以看到没有参加张三老师课程的位置都为 NULL 直接使用 join 即可

    select *
    from SC
    join (
    select cid
    from Teacher
    join Course C on Teacher.TId = C.TId
    where Tname = '张三') as SR
    on SC.CId = SR.CId;
    
    SId CId score cid
    1 02 90.0 02
    2 02 60.0 02
    3 02 80.0 02
    4 02 30.0 02
    5 02 87.0 02
    7 02 89.0 02

    目前 Sid 就已经参加 张三老师课程 的学生 Sid 目前只需要从 Student 中 not in 即可

    select * from Student 
    where SId not in (
    select SId
    from SC
    join (
    select cid
    from Teacher
    join Course C on Teacher.TId = C.TId
    where Tname = '张三') as SR
    on SC.CId = SR.CId);
    
    Id Sname Sage Ssex
    6 吴兰 1992-01-01 00:00:00
    9 张三 2017-12-20 00:00:00
    0 李四 2017-12-25 00:00:00
    1 李四 2012-06-06 00:00:00
    2 赵六 2013-06-13 00:00:00
    3 孙七 2014-06-01 00:00:00
  14. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
    首先从 SC 表中查出 60 分以下并且大于等于 2 学生信息 使用分组即可

    select SId, count(*) as num, avg(score) as avg_num
    from SC
    where score < 60
    group by Sc.SId
    having num >= 2;
    
    SId num avg_num
    4 3 33.33333
    6 2 32.50000

    现在 Sid 和平均分已经有了,只需要和学生表进行连接即可

    select Si.Sid, Sname, avg_num
    from Student
         join
    (select SId, count(*) as num, avg(score) as avg_num
    from SC
    where score < 60
    group by Sc.SId
    having count(1) >= 2) as Si
    on Si.SId = Student.SId;
    
    id Sname avg_num
    4 李云 33.33333
    6 吴兰 32.50000
  15. 检索" 01 "课程分数小于 60,按分数降序排列的学生信息
    这道题相对容易 SC 查询到相关信息然后连接 Student 即可

    select Student.*, score from Student
    join (select SId, score
    from SC
    where CId = '01' and score < 60) as Si
    on Student.SId = Si.SId
    order by score desc;
    
  16. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
    先查询出平均分然后与 SC 表进行连接即可

    select SC.SId, score, avg_num.avg_score from SC join
    (select sid, avg(score) as avg_score from sc group by sid) avg_num
    on SC.SId = avg_num.SId
    order by avg_score desc ;
    
    Id score avg_score
    7 89.0 93.50000
    7 98.0 93.50000
    1 80.0 89.66667
    1 90.0 89.66667
    1 99.0 89.66667
    5 76.0 81.50000
    5 87.0 81.50000
    3 80.0 80.00000
    3 80.0 80.00000
    3 80.0 80.00000
    2 60.0 70.00000
    2 80.0 70.00000
    2 70.0 70.00000
    4 50.0 33.33333
    4 30.0 33.33333
    4 20.0 33.33333
    6 31.0 32.50000
    6 34.0 32.50000
  17. 查询各科成绩最高分、最低分和平均分
    直接按照 Cid 进行分组即可然后连接 Course 即可

    select Course.Cname, max_score, min_score, avg_score
    from Course
         join
     (select CId, max(score) max_score, min(score) min_score, avg(score) 			avg_score
      from SC
      group by CId) as Si
     on Si.CId = Course.CId;
    
    Cname max_score min_score avg_score
    语文 80.0 31.0 64.50000
    数学 90.0 30.0 72.66667
    英语 99.0 20.0 68.50000

    扩展:继上题目 课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率 (及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90)
    在这里插入图片描述

    name max_score min_score avg_score p_pate d_rate hd_rate
    80.0 31.0 64.50000 0.6667 0.5000 0.0000
    90.0 30.0 72.66667 0.6667 0.5000 0.1667
    99.0 20.0 68.50000 0.6667 0.3333 0.3333
  18. 查询出只参加两门课程考试的学生学号和姓名
    通过 SC 表查出参与两门课程的同学信息然后连接 Student 表即可

    select S.SId, S.Sname from Student as S
    join (select SId, count(SC.CId) as num
    from SC
    group by SC.SId) as Si on S.SId = Si.SId
    where num = 2;
    
    id sname
    5 周梅
    6 吴兰
    7 郑竹
  19. 查询男生、女生人数

    select Ssex, count(1)
    from Student
    group by Student.Ssex;
    
    sex count(1)
    8
    4
  20. 查询名字中含有 风 字的学生信息

    select * from student where sname like '%风%';
    
    Id Sname Sage Ssex
    3 孙风 1990-12-20 00:00:00
  21. 查询同名同姓学生名单,并统计人数

    select Sname,count(*) as num
    from Student
    group by Student.Sname
    having num > 1;
    
    Sname num
    李四 2
  22. 查询1990年出生的学生名单

    select * from Student where date_format(Sage, '%Y') = 1990;
    
    Id Sname Sage Ssex
    1 赵雷 1990-01-01 00:00:00
    2 钱电 1990-12-21 00:00:00
    3 孙风 1990-12-20 00:00:00
    4 李云 1990-12-06 00:00:00
  23. 查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号排序

    select cid, avg(score) as avgScore from sc
    group by cid order by avgScore desc, cid asc ;
    
  24. 查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩

    select Si.SId, Student.Sname, Si.avg_score from Student
    join
    (select sid, avg(score) as avg_score from SC
    group by SC.SId
    having avg_score > 85) as Si on Student.SId = Si.SId;
    
    Id Sname avg_score
    1 赵雷 89.66667
    7 郑竹 93.50000
  25. 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数

    select S2.SId, S2.Sname, Course.Cname, S.score
    from Course
         join SC S on Course.CId = S.CId
         join Student S2 on S.SId = S2.SId
    where Course.Cname = '数学' and score < 60;
    
    Id Sname Cname score
    4 李云 数学 30.0
  26. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)

    select Student.SId, Student.Sname, Course.Cname, S.score
    from Student
    left join SC S on Student.SId = S.SId
    left join Course on S.CId = Course.CId;
    
    Id Sname Cname score
    1 赵雷 语文 80.0
    2 钱电 语文 70.0
    3 孙风 语文 80.0
    4 李云 语文 50.0
    5 周梅 语文 76.0
    6 吴兰 语文 31.0
    1 赵雷 数学 90.0
    2 钱电 数学 60.0
    3 孙风 数学 80.0
    4 李云 数学 30.0
    5 周梅 数学 87.0
    7 郑竹 数学 89.0
    1 赵雷 英语 99.0
    2 钱电 英语 80.0
    3 孙风 英语 80.0
    4 李云 英语 20.0
    6 吴兰 英语 34.0
    7 郑竹 英语 98.0
    9 张三 NULL NULL
    0 李四 NULL NULL
    1 李四 NULL NULL
    2 赵六 NULL NULL
    3 孙七 NULL NULL
  27. 查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数

    select S2.SId, S2.Sname, C.Cname, S.score
    from Course C
         join SC S on C.CId = S.CId
         join Student S2 on S.SId = S2.SId
    where S.score > 70;
    
    Id Sname Cname score
    1 赵雷 语文 80.0
    1 赵雷 数学 90.0
    1 赵雷 英语 99.0
    2 钱电 英语 80.0
    3 孙风 语文 80.0
    3 孙风 数学 80.0
    3 孙风 英语 80.0
    5 周梅 语文 76.0
    5 周梅 数学 87.0
    7 郑竹 数学 89.0
    7 郑竹 英语 98.0
  28. 查询每门课程不及格的人数

    select Course.CId, Course.Cname, TempC.sn from Course join
    (select Cid, count(*) as sn from SC where score < 60 group by CId) as TempC
    on TempC.CId = Course.CId;
    
    Id Cname sn
    1 语文 2
    2 数学 1
    3 英语 2
  29. 查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名

    select S.SId, S.Sname, SC.score
    from SC	
    join Student S on SC.SId = S.SId
    where SC.CId = 01
    and SC.score >= 80;
    
    Id Sname score
    1 赵雷 80.0
    3 孙风 80.0
  30. 成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
    不想使用子查询就直接将三张表连接在一起即可

    select Student.*, S.score, T.Tname
    from Student
         join SC S on Student.SId = S.SId
         join Course C on S.CId = C.CId
         join Teacher T on C.TId = T.TId
    where T.Tname = '张三'
    order by S.score desc
    limit 1;
    
    Id Sname Sage Ssex score Tname
    1 赵雷 1990-01-01 00:00:00 90.0 张三
  31. 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

    select distinct a.*
    from sc a
         inner join sc b on a.score = b.score
    where a.CId != b.CId;
    
    Id CId score
    2 03 80.0
    3 02 80.0
    3 03 80.0
    1 01 80.0
    3 01 80.0
  32. 统计每门课程的学生选修人数(超过 5 人的课程才统计)

    select Cname, count(*) as num
    from SC
         join Course C on SC.CId = C.CId
    group by C.Cname
    having num > 5;
    
    name num
    6
    6
    6
  33. 统计每门课程的学生选修人数(超过 5 人的课程才统计)

    select S.Sname, count(SC.CId) as num
    from SC
         join Student S on SC.SId = S.SId
    group by S.Sname
    having num >= 2;
    
    name num
    吴兰 2
    周梅 2
    孙风 3
    李云 3
    赵雷 3
    郑竹 2
    钱电 3
  34. 查询选修了全部课程的学生信息

    select Sname, count(CId) selection_num
    from SC
         join Student S on SC.SId = S.SId
    group by S.Sname
    having selection_num = (select count(1) from Course);
    
    name selection_num
    孙风 3
    李云 3
    赵雷 3
    钱电 3
  35. 查询各学生的年龄,只按年份来算

    -- 两种方法都可以
    select sname, timestampdiff(year, sage, now()) as sage from student;
    select sname, year(now()) - year(sage) as sage from student;
    
    name sage
    赵雷 30
    钱电 30
    孙风 30
    李云 30
    周梅 29
    吴兰 28
    郑竹 31
    张三 3
    李四 3
    李四 8
    赵六 7
    孙七 6
  36. 查询本周过生日的学生

    select sname from student where week(Sage) = week(now());
    
    name
    孙七

猜你喜欢

转载自blog.csdn.net/qq_42768234/article/details/106395899
今日推荐