• 数据库【mysql篇】典型的一些练习题目


    班级表 class

    学生表student

    老师表 teacher

    课程表course

     

    成绩表 score

    准备数据

    创建数据库

    create database tang_test charset='utf8';

    创建表

    CREATE TABLE class (
      cid     INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      caption VARCHAR(20)
    )
      DEFAULT CHARSET = 'utf8';
    
    CREATE TABLE student (
      sid      INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      sname    VARCHAR(20),
      gender   VARCHAR(20),
      class_id INT,
      CONSTRAINT fk_clsid FOREIGN KEY (class_id) REFERENCES class (cid)
    )
      DEFAULT CHARSET = 'utf8';
    
    CREATE TABLE teacher (
      tid   INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      tname VARCHAR(32)
    )
      DEFAULT CHARSET = 'utf8';
    
    CREATE TABLE course (
      cid       INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      cname     VARCHAR(20),
      tearch_id INT,
      CONSTRAINT fk_tea FOREIGN KEY (tearch_id) REFERENCES teacher (tid)
    )
      DEFAULT CHARSET = 'utf8';
    
    CREATE TABLE score (
      sid        INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      student_id INT,
      corse_id   INT,
      number     INT,
      CONSTRAINT fk_sco_stu FOREIGN KEY (student_id) REFERENCES student (sid),
      CONSTRAINT fk_sco_cor FOREIGN KEY (corse_id) REFERENCES course (cid)
    )
      DEFAULT CHARSET = 'utf8';
    View Code

    添加联合唯一约束

    ALTER TABLE score
      ADD UNIQUE i_stu_cor(student_id, corse_id);

    题目与答案

    # 查询“生物”课程比“物理”课程成绩高的所有学生的学号;
    SELECT tb1.student_id
    FROM (SELECT
            student_id,
            number
          FROM score s LEFT JOIN course c ON s.corse_id = c.cid
          WHERE c.cname = '体育') AS tb1 LEFT JOIN (
                                                   SELECT
                                                     student_id,
                                                     number
                                                   FROM score s LEFT JOIN course c ON s.corse_id = c.cid
                                                   WHERE c.cname = '物理') AS tb2 ON tb1.student_id = tb2.student_id
    WHERE tb1.number > tb2.number;
    
    # 查询平均成绩大于60分的同学的学号和平均成绩;
    SELECT
      s.sid,
      avg(number)
    FROM score
      LEFT JOIN student s ON score.student_id = s.sid
    GROUP BY s.sid
    HAVING avg(number) > 60;
    
    # 查询所有同学的学号、姓名、选课数、总成绩;
    SELECT
      student.sid,
      student.sname,
      count(s.corse_id),
      sum(s.number)
    FROM student
      LEFT JOIN score s ON student.sid = s.student_id
    GROUP BY student.sid;
    
    # 查询姓“李”的老师的个数;
    SELECT count(tid)
    FROM teacher
    WHERE tname LIKE "李%";
    
    # 查询没学过“叶平”老师课的同学的学号、姓名;
    SELECT
      sid,
      sname
    FROM student
    WHERE sid NOT IN (
      SELECT DISTINCT student_id
      FROM score
      WHERE corse_id IN (
        SELECT course.cid
        FROM course
          LEFT JOIN teacher t ON course.tearch_id = t.tid
        WHERE t.tname = "叶平"
      ));
    
    # 查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
    SELECT
      tb2.sid,
      tb2.sname
    FROM
      (SELECT
         student_id,
         corse_id
       FROM score
       WHERE corse_id = 2 OR corse_id = 3) AS tb1
      LEFT JOIN student tb2 ON tb2.sid = tb1.student_id
    GROUP BY student_id
    HAVING count(student_id) > 1;
    
    # 查询学过“叶平”老师所教的所有课的同学的学号、姓名;
    SELECT
      student.sid,
      student.sname
    FROM student
    WHERE sid IN (
      SELECT DISTINCT student_id
      FROM score
      WHERE corse_id IN (
        SELECT course.cid
        FROM course
          LEFT JOIN teacher t ON course.tearch_id = t.tid
        WHERE t.tname = '苍空')
    );
    
    # 9.查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
    # 跟第一题差不多
    
    # 查询有课程成绩小于60分的同学的学号、姓名;
    SELECT
      student.sid,
      student.sname
    FROM student
    WHERE sid IN (
      SELECT DISTINCT student_id
      FROM score
      WHERE number < 60
    );
    
    # 查询没有学全所有课的同学的学号、姓名;
    SELECT
      sid,
      sname
    FROM student
    WHERE sid IN (
      SELECT student_id
      FROM score
      GROUP BY student_id
      HAVING count(number) = (
        SELECT COUNT(1)
        FROM course));
    
    SELECT
      s.sid,
      s.sname
    FROM score
      LEFT JOIN student s ON score.student_id = s.sid
    GROUP BY score.student_id
    HAVING count(number) = (SELECT count(1)
                            FROM course);
    
    # 查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名;
    #    1 先找到001同学所学的所有课程id
    #    2.条件学号不为1 以及所学课程in 1号学生所学的id里面
    SELECT
      s.sid,
      s.sname
    FROM score
      LEFT JOIN student s ON score.student_id = s.sid
    WHERE student_id != 1
          AND score.corse_id IN (
      SELECT corse_id
      FROM score
      WHERE student_id = 1)
    GROUP BY student_id;
    
    # 查询至少学过学号为“002”同学所有课的其他同学学号和姓名;
    SELECT
      student_id,
      sname,
      count(score.corse_id)
    FROM score
      LEFT JOIN student s ON score.student_id = s.sid
    WHERE score.student_id != 2 AND score.corse_id IN (
      SELECT corse_id
      FROM score
      WHERE student_id = 2)
    GROUP BY student_id
    HAVING count(corse_id) = (SELECT count(corse_id)
                              FROM score
                              WHERE student_id = 2);
    
    
    SELECT
      student_id,
      sname,
      count(corse_id)
    FROM score
      LEFT JOIN student ON score.student_id = student.sid
    WHERE student_id != 1 AND corse_id IN
                              (SELECT corse_id
                               FROM score
                               WHERE student_id = 1)
    GROUP BY student_id
    HAVING count(corse_id) =
           (SELECT count(corse_id)
            FROM score
            WHERE student_id = 1);
    
    # 查询和“001”号的同学学习的课程完全相同的其他同学学号和姓名;
    # 总个数相等  但 不一定所学的就等于1号所学的
    # 2号所学的课程都被学到  但验证不了总个数相等
    SELECT
      student_id,
      sname
    FROM score
      LEFT JOIN student ON score.student_id = student.sid
    # 总的数量=1号总的数量
    WHERE student_id IN (SELECT student_id
                         FROM score
                         WHERE student_id != 2
                         GROUP BY student_id
                         HAVING count(corse_id) = (SELECT count(1)
                                                   FROM score
                                                   WHERE student_id = 2))
          AND corse_id IN (
      # 1号所学的课程数量都已被学到
      SELECT corse_id
      FROM score
      WHERE corse_id IN (SELECT corse_id
                         FROM score
                         WHERE student_id = 2)
      GROUP BY student_id
      HAVING count(corse_id) = (SELECT count(*)
                                FROM score
                                WHERE student_id = 2)
    );
    
    # 15、删除学习“叶平”老师课的score表记录;
    DELETE FROM score
    WHERE score.corse_id IN
          (SELECT cid
           FROM course
             LEFT JOIN teacher t ON course.tearch_id = t.tid
           WHERE t.tname = '叶平');
    
    # 向SC表中插入一些记录,这些记录要求符合以下条件:
    # ①没有上过编号“002”课程的同学学号;
    # ②插入“002”号课程的平均成绩;
    INSERT INTO score (student_id, corse_id, number)
      SELECT
        sid,
        2,
        (SELECT avg(number)
         FROM score
         WHERE corse_id = 2)
      FROM
        student
      WHERE sid NOT IN (
        SELECT student_id
        FROM score
        WHERE corse_id = 2
      );
    
    # 17、按平均成绩从低到高 显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分;
    SELECT
      student_id,
      (SELECT number
       FROM score
         LEFT JOIN course c ON score.corse_id = c.cid
       WHERE c.cname = '生物' AND score.student_id = sc.student_id) AS "生物",
      (SELECT number
       FROM score
         LEFT JOIN course c ON score.corse_id = c.cid
       WHERE c.cname = '物理' AND score.student_id = sc.student_id) AS "物理",
      (SELECT number
       FROM score
         LEFT JOIN course c ON score.corse_id = c.cid
       WHERE c.cname = '体育' AND score.student_id = sc.student_id) AS "体育",
      count(sc.corse_id),
      avg(number)
    FROM score AS sc
    WHERE sc.corse_id IN (SELECT cid
                          FROM course
                          WHERE course.cname = '生物' OR course.cname = '物理' OR course.cname = '体育')
    GROUP BY sc.student_id
    ORDER BY avg(number);
    
    # 18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;
    SELECT
      corse_id,
      c.cname,
      max(number),
      min(number)
    FROM score
      LEFT JOIN course c ON score.corse_id = c.cid
    GROUP BY corse_id;
    
    # 19、按各科平均成绩从低到高和及格率的百分数从高到低顺序;
    # 思路:case when .. then
    SELECT
      corse_id,
      avg(number)                      AS avgnum,
      sum(CASE WHEN score.number > 60
        THEN 1
          ELSE 0 END) / count(1) * 100 AS percent
    FROM score
    GROUP BY corse_id
    ORDER BY avgnum ASC, percent DESC;
    
    # 20、课程平均分从高到低显示(显示任课老师)
    SELECT
      avg(number),
      t.tname
    FROM score
      LEFT JOIN course c ON score.corse_id = c.cid
      LEFT JOIN teacher t ON c.tearch_id = t.tid
    GROUP BY corse_id
    ORDER BY avg(number) DESC;
    
    # 21、查询各科成绩前三名的记录:(不考虑成绩并列情况)
    # 思路 先找到第一名和第四名的值
    SELECT
      score.sid,
      score.corse_id,
      score.number,
      T.first_num,
      T.second_num
    FROM score
      LEFT JOIN
      (SELECT
         sid,
         (SELECT number
          FROM score AS s2
          WHERE s2.corse_id = s1.corse_id
          ORDER BY number DESC
          LIMIT 0, 1) AS first_num,
         (SELECT number
          FROM score AS s2
          WHERE s2.corse_id = s1.corse_id
          ORDER BY number DESC
          LIMIT 3, 1) AS second_num,
       FROM score
         AS s1)
        AS T ON score.sid = T.sid
    WHERE score.number <= T.first_num AND score.number >= T.second_num;
    
    # 22、查询每门课程被选修的学生数;
    SELECT
      corse_id,
      count(1)
    FROM score
    GROUP BY corse_id;
    
    # 23、查询出只选修了一门课程的全部学生的学号和姓名;
    SELECT
      s.sid,
      s.sname,
      count(1)
    FROM score
      LEFT JOIN student s ON score.student_id = s.sid
    GROUP BY student_id
    HAVING count(1) = 1;
    
    # 24、查询男生、女生的人数;
    # 男生总数为一张表 女生总数为一张表,每张表里面都只有一个字段
    # 查询两张表
    SELECT *
    FROM
      (SELECT count(1) AS man
       FROM student
       WHERE student.gender = '') AS A,
      (SELECT count(1) AS wuman
       FROM student
       WHERE student.gender = '') AS B
    
    # 25、查询姓“张”的学生名单;
    SELECT *
    FROM student
    WHERE sname LIKE '张%';
    
    # 26、查询同名同姓学生名单,并统计同名人数;
    SELECT
      sname,
      count(1)
    FROM student
    GROUP BY sname;
    
    # 27、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列;
    SELECT
      corse_id,
      avg(if(isnull(number), 0, number)) AS avg
    FROM score
    GROUP BY corse_id
    ORDER BY avg ASC, corse_id DESC
    
    # 28、查询平均成绩大于85的所有学生的学号、姓名和平均成绩;
    SELECT
      s.sid,
      s.sname,
      avg(if(isnull(number), 0, number)) AS avg
    FROM score
      LEFT JOIN student s ON score.student_id = s.sid
    GROUP BY student_id
    HAVING avg > 85;
    
    # 29、查询课程名称为“数学”,且分数低于60的学生姓名和分数;
    SELECT
      s.sid,
      s.sname,
      score.number
    FROM score
      LEFT JOIN student s ON score.student_id = s.sid
      LEFT JOIN course c ON score.corse_id = c.cid
    WHERE c.cname = '数学' AND number < 60;
    
    # 30、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名;
    SELECT
      s.sid,
      s.sname,
      score.number,
      score.corse_id
    FROM score
      LEFT JOIN student s ON score.student_id = s.sid
    WHERE corse_id = '3' AND number > 80;
    
    # 31、求选了课程的学生人数
    # 第一种做法
    SELECT count(DISTINCT student_id)
    FROM score;
    
    # 第二种做法
    SELECT count(c)
    FROM (
           SELECT count(student_id) AS c
           FROM score
           GROUP BY student_id) AS A;
    
    # 查询选修“杨艳”老师所授课程的学生中,成绩最高的学生姓名及其成绩;
    # 思路 先找到杨艳所教的课程id,然后再根据课程id分组 排序取第一个
    SELECT
      corse_id,
      s.sname,
      score.number
    FROM score
      LEFT JOIN student s ON score.student_id = s.sid
    WHERE score.corse_id IN (SELECT course.cid
                             FROM course
                               LEFT JOIN teacher t ON course.tearch_id = t.tid
                             WHERE t.tname = '波多')
    ORDER BY number DESC
    LIMIT 1;
    
    # 33、查询各个课程及相应的选修人数;
    SELECT
      corse_id,
      count(1),
      c.cname
    FROM score
      LEFT JOIN course c ON score.corse_id = c.cid
    GROUP BY corse_id;
    
    # 34、查询不同课程但成绩相同的学生的学号、课程号、学生成绩;
    # 同一张表进行链表操作
    SELECT DISTINCT
      s1.corse_id,
      s2.corse_id,
      s1.number,
      s2.number,
      s1.student_id,
      s2.student_id
    FROM score AS s1, score AS s2
    WHERE s1.corse_id != s2.corse_id AND s1.number = s2.number
    
    # 35、查询每门课程成绩最好的前两名;
    # 思路 先找到第一名跟第二名同学的成绩 组成一张新的表
    
    SELECT
      score.sid,
      corse_id,
      score.number
    FROM score
      LEFT JOIN
      (SELECT
         sid,
         (SELECT number
          FROM score AS s2
          WHERE s2.corse_id = s1.corse_id
          ORDER BY number DESC
          LIMIT 1 OFFSET 0) AS first_num,
         (SELECT number
          FROM score AS s2
          WHERE s2.corse_id = s1.corse_id
          ORDER BY number DESC
          LIMIT 1 OFFSET 1) AS second_num
       FROM score AS s1)
        AS T
        ON score.sid = T.sid
    WHERE score.number <= T.first_num AND score.number >= T.second_num
    ORDER BY score.corse_id DESC, score.number DESC;
    
    # 36、检索至少选修两门课程的学生学号;
    SELECT score.sid
    FROM score
    GROUP BY student_id
    HAVING count(student_id) > 1;
    
    # 37、查询全部学生都选修的课程的课程号和课程名;
    SELECT
      cid,
      course.cname
    FROM course
    WHERE course.cid IN
          (SELECT corse_id
           FROM score
           GROUP BY corse_id
           HAVING count(1) = (SELECT count(1)
                              FROM student));
    
    # 38、查询没学过“叶平”老师讲授的任一门课程的学生姓名;
    # 先找到叶平老师所教的课程id
    # 然后找到有学过任意一门是属于叶平老师的课的学生id
    # 然后学生不在里面
    SELECT student.sname
    FROM student
    WHERE sid NOT IN (
      SELECT student_id
      FROM score
      WHERE score.corse_id IN (
        SELECT cid
        FROM course
          LEFT JOIN teacher ON course.tearch_id = teacher.tid
        WHERE tname = '苍空'
      )
    );
    
    # 错误的做法
    # select student_id,student.sname from score
    #   left join student on score.student_id = student.sid
    #   where score.corse_id not in (
    #       select cid from course left join teacher on course.tearch_id = teacher.tid where tname = '张磊老师'
    #   )
    #   group by student_id
    
    # 39、查询两门以上不及格课程的同学的学号及其平均成绩;
    SELECT student_id,count(1) FROM score WHERE number < 60
    GROUP BY student_id
    HAVING count(1) > 2;
    
    # 40、检索“004”课程分数小于60,按分数降序排列的同学学号;
    SELECT student_id,number FROM score WHERE number < 60 and corse_id = 4
    ORDER BY number DESC;
    
    # 41、删除“002”同学的“001”课程的成绩;
    # SELECT * FROM score WHERE student_id = 2 and corse_id = 1;
    DELETE FROM score WHERE student_id = 2 and corse_id = 1;
    View Code

     转载自:http://www.cnblogs.com/wupeiqi/ 

  • 相关阅读:
    log4j日志输出级别(转)
    spring-framework——hao123
    gradle配置国内镜像
    项目启动控制台严重: Error listenerStart问题定位
    Pycharm按键失灵
    Mixed Content混合内容错误 Iframe Http页面无法访问
    RSA加密公钥系数获取结果多00
    xml报文标签替换正则表达式
    AES采用CBC模式128bit加密工具类
    js进行MD5加密(含中文),与后台JAVA加密之后结果不同(解决)
  • 原文地址:https://www.cnblogs.com/tangkaishou/p/10216092.html
Copyright © 2020-2023  润新知