• Mysql 入门 50题目解析


    Mysql 入门 50题目解析

    # 表结构

    # Student                    Course                  Teacher Score

    # 学生表         课程表      教师表             成绩表

    #     学生ID 主键 s_id        课程ID 主键    c_id     教师ID 主键 t_id     学生ID 主键 s_id

    # 学生姓名    s_name        课程名字    c_name     教师姓名     t_name     课程ID    c_id

    #     学生生日    s_birth         课程教师ID    t_id    课程分数 s_score

    #     学生性别 s_sex

    use test;
    show tables;
    show table status;

    select *
     from student;
    select *
     from
     Course;
    select *
     from teacher;
    select *
     from score;
    alter table score;

    # 1 查询"01"课程比"02"课程成绩高的学生的信息及课程分数

    # 思路:

    # 1.1 查询所有选修01和02的课程的学生

    select s_id, score from sc where sc.c_id='01';

    select s_id, s_score  from score where score.c_id='01';  # as t01
    select s_id, s_score  from score where score.c_id='02';  # as t02

     

    # 1.2 选出01课程02的课程比02课程分数高的学生ID

    select t1.s_id,t2.s_id, t1.s_score, t2.s_score from (

        (select s_id, s_score from score where score.c_id='01') as t1,

    (select s_id, s_score from score where score.c_id='02') as t2

    )

    where t1.s_id = t2.s_id and t1.s_score > t2.s_score;

     

    # 1.3 使用join关联学生信息表,查询出所有学生信息

    select * from student right join( #右连接

     

        select t1.s_id, class1, class2 from (

        (select s_id, s_score as class1 from score where score.c_id='01') as t1,

    (select s_id, s_score as class2 from score where score.c_id='02') as t2

            )

        where t1.s_id = t2.s_id and t1.class1 > t2.class2

    ) as r # 01课程比01课程分数多的学生的id 以及课程分数

    on student.s_id = r.s_id;

     

     

    # 2 查询同时在01和02课程的学生 条件查询

    # 2.1 直接借鉴上一题目

    select * from

        (select * from score where score.s_id = '01') as t01,

    (select * from score where score.s_id = '02') as t02

            

    where t01.s_id = t02.s_id;

     

    # 3 查询学生课程 有01 但是不一定有02 不存在为null

    select * from

        (select * from score where score.s_id = '01') as t01

    left join

    (select * from score where score.s_id = '02') as t02

        on t01.s_id = t02.s_id;

     

     

    # 4 查询学生没学过" 01 "课程但学过" 02 "课程的情况

    # 4.1 查询出学习01课程的学生

    # 4.2 以4.1为条件进行过滤查询

     

    # 4.1 code

    select s_id from score where score.s_id = '01';

    # 4.2 code

    select * from score

        where score.s_id

    not in(select s_id from score where score.s_id = '01')

    and score.s_id = '02';

     

     

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

    # 5.1 在 score分数表中使用id分组 对分组数据avg求均值

    # 5.2 使用join 对score表 以及student表进行关联查询 筛选出id name avg-score

     

    # 5.1 code

    select s_id, avg(s_score) as avgss

        from score

    group by s_id

    having avg(s_score) >60;

     

    # 5.2

    select student.s_id, student.s_name, scoreavg.avgss from

        student right join (

     

    select s_id, avg(s_score) as avgss

        from score

    group by s_id

    having avg(s_score) >60) as scoreavg on student.s_id = scoreavg.s_id;

     

    # 6 查询score表中存在成绩的学生信息

    # distinct 区分 进行唯一查询

    # 也可以使用关联查询,但是比较麻烦

    select distinct student.* from student, score where student.s_id = score.s_id;

     

    # 7 查询所学生的编号,姓名,选课总数,所有课程成绩的总成绩

    # 7.1 所有课程成绩的总和,需要group by 分组 求和

    # 7.2 需要所有的学生信息,需要join 连接student表

     

    # 7.1

    select s_id, sum(score.s_score) from score group by score.s_id having sum(score.s_score);

     

    # 7.2

    select

        student_info.s_id,

        student_info.s_name,

    count(score_info.c_id) as sum_course,

    sum(score_info.s_score) as sum_score

    from

        student as student_info

    left join score as score_info on student_info.s_id = score_info.s_id

    group by

        student_info.s_id;

     

    # 8 查询 所有姓李的老师的数量

    # 8.1 使用 like % 模糊匹配

     

    select count(teacher.t_id) from teacher where teacher.t_name like '李%';

     

    # 9 查询学过 张三 老师课程的学生的信息

    # 9.1 在teacher 表 找到 张三 老师的id

    # 9.2 在course 表 找到所有张三老师的课程ID

    # 9.3 在score表和student表中联以课程ID 为条件进行联合查询

     

    # 9.1

    select t_id from teacher where t_name = '张三';

    # 9.2

    select c_id from course where course.t_id = (select t_id from teacher where t_name = '张三');

    # 9.3

    select *

    from

        student as student_info join score as score_info on student_info.s_id = score_info.s_id

    where

        score_info.c_id in

     

    (select c_id

    from

            course

        where course.t_id = (select t_id from teacher where t_name = '张三'));

     

    # 9 方法二

    select

        student.*, score.c_id

    from

        student, teacher, course, score

    where

        student.s_id = score.s_id

    and

        course.c_id = score.c_id

    and

        course.t_id = teacher.t_id

    and

        t_name = '张三';

     

    # 10 查询没学过 张三老师课程的学生的信息

    # 同上 使用 not in

     

    # 方法 1

    select *

    from

        student as student_info join score as score_info on student_info.s_id = score_info.s_id

    where

        score_info.c_id not in

     

    (select c_id

    from

            course

        where course.t_id = (select t_id from teacher where t_name = '张三'));

     

    # 方法 2

    select

        student.*, score.c_id

    from

        student, teacher, course, score

    where

        student.s_id = score.s_id

    and

        course.c_id = score.c_id

    and

        course.t_id = teacher.t_id

    and

        t_name != '张三';

     

    # 11 查询没有学全所有课程的学生

    # 反向思维,有学全的就有没有学全的 (漏洞 可能都没有学全)

    # 或者

    # 在course表中count 课程数

    # 在score表中group by student id count 课程数 小于所有课程数的就是没有学全的

     

    # 方法 1 查找出学全的课程的学生ID

    select score.s_id, count(score.s_id) from score group by score.s_id having count(score.s_id) = (select count(course.c_id) from course);

     

    # 方法 2

    select student_info.* from student as student_info left join score as score_info on student_info.s_id = score_info.s_id

    group by

        student_info.s_id

    having

        count(score_info.c_id) < (select count(course.c_id) from course);

     

    # 12 查询至少有一门课程 和 01号学生 所学的课程相同的学生的信息

    # 1 从score表中查询 01号 学生所学所有课程的 c_id

    # 2 从score表中查询涉及c_id 课程的所有学生的s_id

    # 3 从student表中查询包含的s_id 的信息

     

    # step 1

    select score.c_id from score where score.s_id = '01';

    # step 2

    select score.s_id from score where score.c_id in (select score.c_id from score where score.s_id = '01');

    # step 3

    select

        student.*

    from

        student

    where

        student.s_id

    in

        (select score.s_id from score where score.c_id in (select score.c_id from score where score.s_id = '01'));

     

    # 13 查询所有和 01号 学生所学相同的课程的学生

    # 1 从score表中group concat 出 01号的课程c_id

    # 2 从score中group concat 所有学生的课程c_id

    # 3 找出group concat 相同的 s_id

    # 4 从student 中查询找到的s_id 信息

     

    # 13.1 01 号学生 的课程

    select score.s_id, group_concat(score.c_id) from score group by score.s_id having score.s_id = '01';

    # (select score.s_id, group_concat(score.c_id) from score group by score.s_id having score.s_id = '01') as 01group_concat;

     

    # 13.2 所有学生的课程

    select score.s_id, group_concat(score.c_id) from score group by score.s_id;

    # (select score.s_id, group_concat(score.c_id) from score group by score.s_id) as allgroup_concat

     

    # 13.3 选出所有学生中group_concat c_id = group_concat 01 c_id 的s_id

    select allgroup_concat.s_id

    from

        (select score.s_id, group_concat(score.c_id) as all_concat from score group by score.s_id) as allgroup_concat,

    (select score.s_id, group_concat(score.c_id) as 01_concat from score group by score.s_id having score.s_id = '01') as 1_group_concat

    where

        allgroup_concat.all_concat = 1_group_concat.01_concat;

     

    # 13.4 从student中选出3中的s_id的学生信息 并且排除掉01号本身

    select * from student

    where

        student.s_id in

    (

        select allgroup_concat.s_id

        from

        (select score.s_id, group_concat(score.c_id) as all_concat from score group by score.s_id) as allgroup_concat,

    (select score.s_id, group_concat(score.c_id) as 01_concat from score group by score.s_id having score.s_id = '01') as 1_group_concat

        where

        allgroup_concat.all_concat = 1_group_concat.01_concat

    )

    and

        student.s_id != '01';

     

     

    # 14 查询没有学过 张三老师 课程的学生信息

     

    # 从teacher表中查询老师id

    # 从course中通过teacherid找到courseid

    # 从score中通过courseid找到student id

     

    # 14.1

    select teacher.t_id from teacher where teacher.t_name = '张三';

     

    # 14.2

    select course.c_id from course where course.t_id in (select teacher.t_id from teacher where teacher.t_name = '张三');

     

    # 14.3

    select score.s_id from score where score.c_id in

        (select course.c_id from course where course.t_id in

            (select teacher.t_id from teacher where teacher.t_name = '张三'));

     

    # 14.4

    select * from student where student.s_id in

        (select score.s_id from score where score.c_id in

            (select course.c_id from course where course.t_id in

                (select teacher.t_id from teacher where teacher.t_name = '张三')));

     

    # 15 查询两门机器以上不及格的学生的学号,姓名,平均成绩

    # 从score中选出score小于60的

    # group by s_id count score.s_score >1

     

    # 15.1 # 在score表中选出成绩低于60的

    select * from score where score.s_score < 60;

     

    # 15.2 # 在score对选出成绩<60的进行分组, 这样才能统计低于60的科目有几科

    select *, group_concat(score.s_score) from score where score.s_score < 60 group by score.s_id;

     

    # 15.3 # 在score中对分组后的<60的进行计数

    select *, group_concat(score.s_score)from score where score.s_score < 60 group by score.s_id having count(*) > 1;

     

    # 15.4

    select

        student.s_id, student.s_name, avg(score.s_score), group_concat(score.s_score)

    from

        student, score

    where

        student.s_id = score.s_id

    and

        score.s_score < 60 group by score.s_id having count(*) > 1;

     

    # 16 查询 01课程 分数小于60的学生 按照分数降序排列

    # 16.1 在score中查询01课程小于60的学生

    # 16.02 排序

     

    # 16.01

    select * from score where score.s_score < 60 and score.c_id = '01';

    # 16.02

    select * from score where score.s_score < 60 and score.c_id = '01' order by score.s_score desc;

     

    # 17 所有学生的查询平均成绩按照降序排列 显示 所有课程成绩以及平均成绩

    # 17.1 查出所有学生的平均成绩

    select score.s_id, group_concat(score.s_score), avg(score.s_score) from score group by score.s_id;

    # 17.2 内连接显示成绩

    select * from score

     

    left join

        (select score.s_id, avg(score.s_score) as avgscore from score group by score.s_id) as group_score

    on

        score.s_id = group_score.s_id

    order by

        avgscore

    desc;

     

    # 18 查询各个课程的最高分最低分平均分 按照 课程ID 最高分 最低分 平均分 及格率 中等率 优良率 优秀率 排列

    # 及格( >= 60) 中等(70-80) 优良率(80-90) 优秀率(>90)

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

    # max min avg

    select

        score.s_id,

    max(score.s_score) as '最高分',

    min(score.s_score) as '最低分',

    avg(score.s_score) as '平均分',

    count(*) as '人数',

    sum(case when score.s_score >= 60 then 1 else 0 end )/count(*) as '及格率',

    sum(case when score.s_score >= 70 and score.s_score < 80 then 1 else 0 end )/count(*) as '中等率',

    sum(case when score.s_score >= 80 and score.s_score < 90 then 1 else 0 end )/count(*) as '优良率',

        sum(case when score.s_score >= 90 then 1 else 0 end )/count(*) as '优秀率'

    from

        score

    group by

        score.s_id

    order by

        count(*) desc,

    score.c_id asc;

     

    # 19 按照各个科目的成绩进行排序

     

    # 20 查询学生的总成绩 并进行排名 总分重复的时候不保留名次

     

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

    # 1 course表和score表 group by join 查询

     

    select course.c_name, course.c_id,

        sum(case when score.s_score <=100 and score.s_score>85 then 1 else 0 end) as '[100-85]',

        sum(case when score.s_score <=100 and score.s_score>85 then 1 else 0 end) / count(*) as '%',

        sum(case when score.s_score <=85 and score.s_score>70 then 1 else 0 end) as '[85-70]',

    sum(case when score.s_score <=85 and score.s_score>70 then 1 else 0 end) / count(*) as '%',

        sum(case when score.s_score <=70 and score.s_score>60 then 1 else 0 end) as '[70-60]',

    sum(case when score.s_score <=70 and score.s_score>60 then 1 else 0 end) / count(*) as '%',

        sum(case when score.s_score <=60 and score.s_score>0 then 1 else 0 end) as '[60-0]',

    sum(case when score.s_score <=60 and score.s_score>0 then 1 else 0 end) / count(*) as '%'

    from

        score left join course

        on

    score.c_id = course.c_id

    group by

        score.c_id;

        

    # 22 查询各个科目成绩的前三名的记录

    # 22.1 进行自关联

    # 22.2 当2表比1表大的 前3个记录

     

    select

        t1.s_id, t1.c_id, t1.s_score

    from

        score as t1 left join score as t2 on t1.c_id = t2.c_id and t1.s_score < t2.s_score

    group by

        t1.s_id, t1.c_id, t1.s_score having count(t2.s_id) < 3

    order by

        t1.c_id;

     

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

    # 使用 嵌套查询

    # 1 对score按照s id分组

    # 2 联合student表进行查询

     

    select student.s_id, student.s_name from student

    where

        student.s_id in

    (select score.s_id from score group by score.s_id having count(score.c_id) = 2);

     

    # 24 查询男生人数

    # group by 分组查询

    select student.s_sex, count(student.s_sex) from student group by student.s_sex;

     

    # 25 .查询同名学生名单,并统计同名人数

    # 按照名字进行group by 找到同名的名字并统计个数

     

    select student.s_name, count(student.s_name) from student group by student.s_name having count(*)>1;

     

    # 26 查询 1990 年出生的学生名单

    # 简单条件查询

    select * from student where year(student.s_birth) = 1990;

     

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

    select score.s_id, course.c_name, avg(score.s_score) as avgscore from score, course where score.c_id = course.c_id group by score.c_id order by avgscore desc, course.c_id asc;

     

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

     

    # 1 在score表中 group by s id 找到avg > 70 的 s id

    select *, group_concat(score.s_score), avg(score.s_score) from score group by score.s_id having avg(score.s_score) >85;

    # 2 嵌套查询

    select

            *                                #student.*, avg(score.s_score) as avgscore

    from

        score, student

    where

        score.s_id = student.s_id

    group by

        score.s_id

    having

        avg(score.s_score) > 85;

     

     

    # 29 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数

    # 条件查询

    select * from score, student, course where student.s_id = score.s_id and course.c_id = score.c_id and score.s_score < 60;

     

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

    # 左连接查询 链接 student score

    select * from student left join score on student.s_id = score.s_id;

     

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

    # 多表查询

    select * from student, course, score where student.s_id = score.s_id and score.c_id = course.c_id and score.s_score > 70;

     

    # 32 查询存在不及格的课程ID

    # group by 来取唯一,也可以用distinct

    select * from score where score.s_score < 60 group by score.c_id;

     

     

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

    # 多条件查询

    select * from score, student where score.s_id = student.s_id and score.s_score >= 80 and score.c_id = '01';

     

    # 34 求每门课程的学生人数

    # 在score表中group by c_id

    select *, count(score.s_id) from score group by score.c_id;

     

    # 35 查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩 (成绩不重复的时候)

    # 涉及表 course teacher score student

     

    select * from teacher, course, score, student

    where

        teacher.t_id = course.t_id

    and

    course.c_id = score.c_id

    and

    score.s_id = student.s_id

    and

    teacher.t_name ='张三'

    order by

        score.s_score desc limit 1;

     

    # 36 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

    # 内连接 链接条件即成绩相同 课程不同

    # distinct 去重

    select

        distinct score_info1.s_id,score_info1.c_id,score_info1.s_score

    from

        score as score_info1, score as score_info2

    where

        score_info1.s_score = score_info2.s_score and score_info1.c_id != score_info2.c_id;

     

    # 37 查询每门功成绩最好的前两名

    # 内连接 通过每次的对比找出最大的前两条

    select

        *

    from

        score as score_info1 left join score as score_info2 on score_info1.c_id = score_info2.s_id and score_info1.s_score < score_info2.s_score

    group by

        score_info1.c_id, score_info2.c_id

    having

        count(score_info2.c_id) < 2

    order by

        score_info1.c_id;

     

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

    select *, count(score.s_id) as countcid from score group by score.c_id having count(countcid) > 5;

     

    # 38 查询至少选修两门课程的学生学号

    # 对score group by sid

    select distinct *, group_concat(score.c_id) from score group by score.s_id having count(score.c_id) >1;

     

    # 39 查询选修了全部课程的学生信息

    # distinct 出表course的课程

    # 在score表中选出与课程数相同的sid

    # 在student表中查询sid信息

     

    select student.*

    from

        student, score

    where

        student.s_id = score.s_id

    group by

        score.s_id having count(score.c_id) = (select distinct count(*) from course);

     

    # 40 查询各学生的年龄,只按年份来算

    # timestampdiff 按照指定时间间隔计算指定日期到某个日趋的间隔时间

    select student.*, (timestampdiff(year, student.s_birth, curdate())) from student;

     

    # 41 查询本周过生日的学生

    # 使用时间函数找出 和当前周相同的学生生日周

    select student.* from student where weekofyear(student.s_birth) = weekofyear(curdate());

     

    # 43 查询下周过生日的学生

    # 使用时间函数找出和当下周(比当前周多一周)的学生生日周

    select student.* from student where weekofyear(student.s_birth) = weekofyear(curdate()) + 1;

     

    # 44 查询本月过生日的学生

    # 原理同上 找出相同月

    select * from student where month(student.s_birth) = month(curdate());

     

    # 45 查询下月过生日的学生

    # 原理同43

    select * from student where month(student.s_birth) = month(curdate()) + 1;

  • 相关阅读:
    成员变量、类变量、局部变量的区别
    微服务学习笔记二:Eureka服务注册发现
    微服务学习笔记一:Spring Cloud简介
    Java集合篇六:Map中key值不可重复的测试
    重写Euqals & HashCode
    Java集合篇五:HashMap
    Java集合篇四:Map的基本应用
    Java集合篇三:Vector
    Java集合篇二:LinkList
    Java集合篇一:ArrayList
  • 原文地址:https://www.cnblogs.com/binyang/p/11288802.html
Copyright © 2020-2023  润新知