zoukankan      html  css  js  c++  java
  • mysql练习题1-41

    Mysql练习:

    联表查询:

    select score.sid,student.sid from score

    left join student on score.student_id=student.sid

    left join course on score.course_id=course.cid

    left join class on student.class_id=class.cid

    left join teacher on teacher.tid=course.teacher_id;

    一、请创建如下表,并创建相关约束

    # 数据库 use work;

    # 班级表

    create table class(

    cid int auto_increment primary key,

    caption varchar(30) not null

    )engine=innodb default charset=utf8;

    # 学生表,关联班级表 cid

    create table student(

    sid int auto_increment primary key,

    sname varchar(30) not null,

    gender varchar(4) not null default “男”,

    class_id int not null,

    constraint fk_class_stu foreign key (class_id ) references class(cid)

    )engine=innodb default charset=utf8;

    # 老师表

    create table teacher(

    tid int auto_increment primary key,

    tname varchar(30) not null

    )engine=innodb default charset=utf8;

    # 课程表,关联 老师表 tid

    create table course(

    cid int auto_increment primary key,

    cname varchar(30) not null,

    teacher_id int not null,

    constraint fk_course_teac foreign key (teacher_id) references teacher(tid)

    )engine=innodb default charset=utf8;

    # 成绩表,关联student  sidcourse cid

    create table score(

    sid int auto_increment primary key,

    student_id int not null,

    course_id int not null,

    number float not null,

    constraint fk_score_stu foreign key (student_id) references student(sid),

    constraint fk_score_cour foreign key (course_id) references course(cid)

    )engine=innodb default charset=utf8;

    二、操作表

    1、自行创建测试数据

    ①查询每个学生所在的班级名称:

    select * from student left join class on student.class_id=class.cid;

    ②查询每门课程的老师的姓名

    select * from course left join teacher on course.teacher_id=teacher.tid;

    ③ 查询每个老师所教了多少门课程:

    select teacher_id,count(cname) from course group by teacher_id;

    ④查询男生女生的个数:

    select gender,count(*) from student group by gender;

    ⑤临时表:

    select sid,number from (select * from score where number>90) as B;

    select sid from (select sid,number from score where number>90) as B;

     

    2、查询生物课程比物理课程成绩高的所有学生的学号;

    # ①连接student和core表,分别 查询到学过生物的 as A、学过物理的as B

    因为表只能横向对比

    (SELECT score.student_id,score.course_id,score.number,course.cname FROM score LEFT JOIN course ON score.course_id=course.cid WHERE course.cname='物理') as A

    # ②连接ABinner join),然后查询到A.number>B.number的学生id

    SELECT A.student_id FROM

    (SELECT score.student_id,score.course_id,score.number,course.cname FROM score LEFT JOIN course ON score.course_id=course.cid WHERE course.cname='物理') as A

    INNER JOIN

    (SELECT score.student_id,score.course_id,score.number,course.cname FROM score LEFT JOIN course ON score.course_id=course.cid WHERE course.cname='生物') as B

    ON A.student_id=B.student_id

    WHERE A.number>B.number;

    3、查询平均成绩大于60分的同学的学号和平均成绩; 

        思路:

            根据学生分组,使用avg获取平均值,通过having对avg进行筛选

    select student_id,avg(number) from score group by student_id having avg(number)>60;

    扩展:查询平均成绩大于60分的同学的学号、姓名和平均成绩; 

    SELECT student.sid,student.sname,B.aaa

    from student

    LEFT JOIN

    (select student_id,avg(number) as aaa from score GROUP BY student_id HAVING avg(number)>60) as B

    ON student.sid=B.student_id;

    4、查询所有同学的学号、姓名、选课数、总成绩;

    SELECT student.sid,student.sname,count(student.sid),sum(score.number) from score

    LEFT JOIN student on score.student_id=student.sid

    GROUP BY student.sid;

    5、查询姓的老师的个数;

    SELECT count(tid) FROM teacher WHERE tname LIKE '%' ;

    6、查询没学过叶平老师课的同学的学号、姓名;

    ①从scorecourse表,找到李平老师所教的课程id

    SELECT cid FROM teacher LEFT JOIN  course ON teacher.tid=course.teacher_id

    WHERE teacher.tname=’李平老师'

    ②从score表筛选出 选过 李平 老师课程的 学生id,并分组去重

    SELECT score.student_id FROM score WHERE score.course_id

    IN (SELECT cid FROM teacher LEFT JOIN  course

    ON teacher.tid=course.teacher_id

    WHERE teacher.tname='’李平老师') GROUP BY student_id

    ③ 联合学生表,筛选出 没选过 叶平 老师课的学生id以及姓名

     

    7、查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;

    score表 筛选学过 001 002 的学生,

    ②然后分组,count(course_id)>1的是同时学过这两门课的

    ③联合student表得到姓名

    SELECT score.student_id,student.sname

     FROM score LEFT JOIN student on score.student_id=student.sid

    WHERE course_id=7 or course_id=8

    GROUP BY student_id HAVING count(course_id)>1

    8查询学过叶平老师所教的所有课的同学的学号、姓名;

    SELECT student.sid,student.sname FROM student WHERE student.sid IN

    (SELECT score.student_id FROM score WHERE score.course_id

    IN

    (SELECT cid FROM teacher LEFT JOIN  course

    ON teacher.tid=course.teacher_id

    WHERE teacher.tname='张益老师') GROUP BY student_id)

    9、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;

    # 学过001as AINNER JOIN,学过002as B

    SELECT student.sid,student.sname FROM

    (

    SELECT A.student_id,A.course_id FROM

    (SELECT * FROM score WHERE course_id=7) as A

    INNER JOIN

    (SELECT * FROM score WHERE course_id=8) as B

    ON A.student_id=B.student_id

    WHERE A.number<B.number) as C

    LEFT JOIN student

    ON  C.student_id=student.sid

    10、查询有课程成绩小于60分的同学的学号、姓名;

    # 先找到成绩<60的,如果遇到某一个同学有多门成绩<60的可以用group byDISTINCT(DISTINCT去重效率不高)

    SELECT sid,sname FROM student WHERE sid IN

    (SELECT DISTINCT student_id FROM score WHERE number<70)

    #group去重

    SELECT sid,sname FROM student WHERE sid IN

    (SELECT student_id FROM score WHERE number<70 GROUP BY student_id)

    11、查询没有学全所有课的同学的学号、姓名;

    #①查询所学课程数量 小于课程总数的

    SELECT student_id,count(1) FROM score GROUP BY student_id

    HAVING count(1)<(SELECT COUNT(cid) FROM course);

    #②找到姓名

    SELECT sid,sname FROM student WHERE sid IN

    (SELECT student_id FROM score GROUP BY student_id

    HAVING count(1)<(SELECT COUNT(cid) FROM course));

    12、查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名;

    # ①先查询到这位同学选的所有的课

    SELECT student_id,course_id FROM score WHERE student_id=1;

    # ②在score表中查到学习了这些课程的学生学号,并排除001自己

    SELECT student_id FROM score WHERE student_id !=1 AND course_id IN

    (SELECT course_id FROM score WHERE student_id=1) GROUP BY student_id);

    # ③联表student拿到姓名

    SELECT student.sid,student.sname FROM score LEFT JOIN student ON score.student_id=student.sid

    WHERE student_id !=1 AND course_id IN

    (SELECT course_id FROM score WHERE student_id=1) GROUP BY student_id;

    13、查询至少学过学号为“001”同学所选课程中任意一门课的其他同学学号和姓名;

    14、查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名

    15、删除学习“叶平”老师课的score表记录;

    16、SC表中插入一些记录,这些记录要求符合以下条件:①没有上过编号“002”课程的同学学号;②插入“002”号课程的平均成绩; 

    #插入score表的值是 查询的结果(其中平均成绩也是动态计算的)

    INSERT INTO score(student_id,course_id,number)

    SELECT student_id,2,(SELECT avg(number) FROM score WHERE course_id=2) FROM score WHERE course_id!=2;

    17、按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分;

    SELECT

    student_id as 学生ID,

    (SELECT number FROM score as s2 WHERE s1.student_id=s2.student_id AND course_id=(SELECT cid FROM course WHERE course.cname='生物')) as 生物,

    (SELECT number FROM score as s2 WHERE s1.student_id=s2.student_id AND course_id=(SELECT cid FROM course WHERE course.cname='Math')) as 数学,

    (SELECT number FROM score as s2 WHERE s1.student_id=s2.student_id AND course_id=(SELECT cid FROM course WHERE course.cname='物理')) as 物理,

    count(s1.course_id) as 有效课程数,

    avg(s1.number) as 有效平均分

    FROM score AS s1

    GROUP BY student_id DESC;

    18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;

    SELECT course_id,MAX(number),MIN(number) FROM score GROUP BY course_id;

    扩展:当最低分<10时显示0,大于等于10时显示实际分数

    SELECT course_id,max(number),case when min(number)<10 THEN 0 ELSE min(number) END as m FROM score GROUP BY course_id;

    19、按各科平均成绩从低到高和及格率的百分数从高到低顺序;

    SELECT course_id,avg(number),sum(1),sum(case when number<60 THEN 0 ELSE 1 END)/sum(1)  as jigel FROM score

    GROUP BY course_id

    ORDER BY avg(number) asc,jigel DESC;

    20、课程平均分从高到低显示(显示任课老师);

    SELECT score.course_id,course.cname,avg(number),teacher.tname FROM score

    LEFT JOIN course ON score.course_id=course.cid

    LEFT JOIN teacher ON teacher.tid=course.teacher_id

    GROUP BY course_id ORDER BY avg(number) desc;

    另外:防止分数里面有null就置为0,再做平均分

     select avg(if(isnull(score.num),0,score.num)),teacher.tname from course

    21、查询各科成绩前三名的记录:(不考虑成绩并列情况

    # 先查询到某一科课程的成绩(避免分数有相同的,用GROUP BY去重

    SELECT number FROM score WHERE course_id=7 GROUP BY number ORDER BY number desc LIMIT 0,1;   #课程7第一名

    SELECT number FROM score WHERE course_id=7 GROUP BY number ORDER BY number desc LIMIT 1,1;   #第二名

    SELECT number FROM score WHERE course_id=7 GROUP BY number ORDER BY number desc LIMIT 2,1;   #第三名

    # 大于第4名的成绩就是前3

    SELECT * FROM

    (

    SELECT

    student_id,course_id,number,

    (SELECT number FROM score as s2 WHERE s2.course_id=s1.course_id GROUP BY  s2.number ORDER BY s2.number desc LIMIT 0,1),

    (SELECT number FROM score as s2 WHERE s2.course_id=s1.course_id GROUP BY  s2.number ORDER BY s2.number desc LIMIT 3,1) as cc

    FROM score as s1

    ) as B

    WHERE B.number > B.cc

    同:第35

    22、查询每门课程被选修的学生数;

    SELECT course_id,count(student_id) FROM score GROUP BY course_id;

    扩展:查询热门课程(选修人数大于>5的)

    SELECT course_id,count(1) FROM score GROUP BY course_id HAVING count(1)>5;

    23、查询出只选修了一门课程的全部学生的学号和姓名;

    #①查询到只学了一门课程的学生的id

    SELECT student_id,count(1) FROM score GROUP BY student_id HAVING count(1)=1

    #②联表

    SELECT score.student_id,student.sname,count(1) FROM score

    LEFT JOIN student ON score.student_id=student.sid

    GROUP BY student_id HAVING count(1)=1;

    24、查询男生、女生的人数;

    SELECT gender,COUNT(1) FROM student GROUP BY gender;

    25、查询姓“张”的学生名单;

    SELECT * FROM student WHERE sname LIKE '%';

    26、查询同名同姓学生名单,并统计同名人数;

    SELECT sname,count(1) FROM student GROUP BY sname;

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

    SELECT course_id,avg(if(isnull(number),0,number)) as avg FROM score GROUP BY course_id

    ORDER BY avg asc,course_id desc;

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

    SELECT score.student_id,student.sname,avg(number) FROM score

    LEFT JOIN student ON student.sid=score.student_id

    GROUP BY score.student_id HAVING avg(number)>85;

    29、查询课程名称为“数学”,且分数低于60的学生姓名和分数;

    SELECT score.student_id,student.sname,course.cname,score.number FROM score

    LEFT JOIN student ON student.sid=score.student_id

    LEFT JOIN course ON score.course_id=course.cid

    WHERE course.cname='生物' and score.number<60;

    30、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名; 

    29题:

    SELECT score.student_id,student.sname,course.cname,score.number FROM score

    LEFT JOIN student ON student.sid=score.student_id

    LEFT JOIN course ON score.course_id=course.cid

    WHERE course.cid=7 and score.number>80;

    31、求选了课程的学生人数

    # group by

    SELECT count(c) FROM

    (SELECT count(course_id) as c FROM score GROUP BY student_id) as A;

    # distinct

    SELECT count(DISTINCT student_id) FROM score;

    32、查询选修“杨艳”老师所授课程的学生中,成绩最高的学生姓名及其成绩;

    #先找到“杨艳”老师所教课程的课程id

    SELECT student.sid,student.sname,score.number FROM score

    LEFT JOIN student ON student.sid=score.student_id

    WHERE score.course_id IN

    (select course.cid FROM teacher LEFT JOIN course

    ON teacher.tid=course.teacher_id

    WHERE teacher.tname='张益老师')

    ORDER BY score.number DESC LIMIT 0,1;

    33、查询各个课程及相应的选修人数;

    SELECT course.cname,count(1) FROM score

    LEFT JOIN course ON course.cid=score.course_id

    GROUP BY course_id;

    34、查询不同课程但成绩相同的学生的学号、课程号、学生成绩;

    #SELECT * FROM  t1, t2;   结果有 t1的条数* t2的条数(笛卡尔积)

    SELECT s1.student_id,s1.course_id,s1.number FROM score as s1,score s2

    WHERE s1.sid != s2.sid AND s1.course_id != s2.course_id AND s1.number=s2.number;

    35、查询每门课程成绩最好的前两名;

    36、检索至少选修两门课程的学生学号;

    SELECT student_id,count(student_id) FROM score

    GROUP BY student_id

    HAVING count(student_id)>1;

    37、查询全部学生都选修的课程的课程号和课程名;

    #score表按照course_id进行分组,每门课程的学生人数=学生的总人数

    SELECT course_id,course.cname,count(1) FROM score

    LEFT JOIN course ON course.cid=score.course_id

    GROUP BY course_id

    HAVING count(student_id)=(SELECT count(1) FROM student);

    38、查询没学过“叶平”老师讲授的任一门课程的学生姓名;

    #①先查询到“叶平”老师任课的课程id

    #score表中查到学习了叶平老师课的所有学生id(不能直接NOT IN,否则不能完整排除)

    #③从student表中找到没有被排除的学生

    SELECT * FROM student WHERE student.sid NOT IN

    (SELECT score.student_id FROM score WHERE score.course_id IN

    (SELECT course.cid FROM course LEFT JOIN teacher ON teacher.tid=course.teacher_id

    WHERE teacher.tname='张益老师'));

    39、查询两门以上不及格课程的同学的学号及其平均成绩;

    #先找到不及格的,再分组计算

    SELECT student_id,avg(number) FROM score WHERE number<80 GROUP BY student_id HAVING count(1)>2;

    40、检索004”课程分数小于60,按分数降序排列的同学学号;

    SELECT * FROM score WHERE course_id=7 AND number<80 ORDER BY number DESC;

    41、删除002”同学的“001”课程的成绩;

    DELETE from score WHERE student_id=2 AND course_id=1;

  • 相关阅读:
    关于C++中类的static和const成员
    你搞图论有毛用啊!!
    getopt()
    算法设计与分析求最大子段和问题(蛮力法、分治法、动态规划法) C++实现
    CF183 div2 解题报告
    程序员面试中什么最重要?
    php函数基础(一)
    可变参数列表
    ThinkPHP5+小程序商城 网盘视频
    svn里update以后还是有红色的感叹号怎么办
  • 原文地址:https://www.cnblogs.com/chenhongl/p/14421461.html
Copyright © 2011-2022 走看看