SQL语句练习

SQL语句练习

练习环境搭建

CREATE DATABASE sql_test CHARSET='utf8';

USE sql_test;

CREATE TABLE tab_student(
    stu_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '学生id,起始2021001',
    stu_name VARCHAR(50) COMMENT '学生姓名',
    stu_age INT COMMENT '学生年龄',
    stu_sex CHAR(1) COMMENT '学生性别'
) COMMENT '学生表';

CREATE TABLE tab_teacher(
    tea_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '教师id,起始10001',
    tea_name VARCHAR(50) COMMENT '教师姓名'
) COMMENT '教师表';

CREATE TABLE tab_course(
    cou_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '课程id,起始1',
    cou_name VARCHAR(50) COMMENT '课程名称',
    tea_id INT COMMENT '教师id',
    CONSTRAINT fk_cou_tea_id FOREIGN KEY(tea_id) REFERENCES tab_teacher(tea_id)
) COMMENT '课程表';

CREATE TABLE tab_score(
    stu_id INT COMMENT '学生id',
    cou_id INT COMMENT '课程id',
    sco_score DOUBLE(4,1) COMMENT '成绩表',
    PRIMARY KEY(stu_id, cou_id),
    CONSTRAINT fk_sco_stu FOREIGN KEY(stu_id) REFERENCES tab_student(stu_id),
    CONSTRAINT fk_sco_cou FOREIGN KEY(cou_id) REFERENCES tab_course(cou_id) 
) COMMENT '成绩表';


INSERT INTO tab_student VALUES(2021001,'赵一',CEIL(RAND()*7+18),IF((RAND()>0.5), '男' ,'女')),
                              (NULL,'钱二',CEIL(RAND()*7+18),IF((RAND()>0.5), '男' ,'女')),
                              (NULL,'孙三',CEIL(RAND()*7+18),IF((RAND()>0.5), '男' ,'女')),
                              (NULL,'李四',CEIL(RAND()*7+18),IF((RAND()>0.5), '男' ,'女')),
                              (NULL,'周五',CEIL(RAND()*7+18),IF((RAND()>0.5), '男' ,'女')),
                              (NULL,'吴六',CEIL(RAND()*7+18),IF((RAND()>0.5), '男' ,'女')),
                              (NULL,'郑七',CEIL(RAND()*7+18),IF((RAND()>0.5), '男' ,'女')),
                              (NULL,'王八',CEIL(RAND()*7+18),IF((RAND()>0.5), '男' ,'女')),
                              (NULL,'冯九',CEIL(RAND()*7+18),IF((RAND()>0.5), '男' ,'女')),
                              (NULL,'陈十',CEIL(RAND()*7+18),IF((RAND()>0.5), '男' ,'女'));

/*查询学生表中数据是否正确被插入*/
SELECT * FROM tab_student;


INSERT INTO tab_teacher VALUES(10001,'褚一'),
                              (NULL,'卫二'),
                              (NULL,'卫二二'),
                              (NULL,'蒋三'),
                              (NULL,'蒋三三'),
                              (NULL,'蒋三三三');

/*查询老师表中数据是否正确被插入*/
SELECT * FROM tab_teacher;

INSERT INTO tab_course VALUES(1,'C语言',10001),
                             (NULL,'Java',10002),
                             (NULL,'操作系统',10003),
                             (NULL,'MySQL',10004),
                             (NULL,'计算机网络',10005),
                             (NULL,'数据结构',10006);

/*查询课程表中数据是否正确被插入*/                             
SELECT * FROM tab_course;

/*随机学生id,课程id,分数,执行多次*/
INSERT INTO tab_score VALUES(CEIL(RAND()*10+2021000),CEIL(RAND()*6),ROUND(RAND()*100,1));

/*查询分数表中数据是否正确被插入*/
SELECT * FROM tab_score;

语句练习

-- 1、查询id为1的课程比id为2的课程,成绩高的所有学生的学号
/*
思路:
1、分别查出课程id为1以及课程id为2的课程,并做笛卡尔积
2、根据要求制定条件,找出学号相同且课程1的分数大于课程2的分数的同学
*/
SELECT score1.stu_id 学生id
FROM 
    (SELECT stu_id,
            sco_score
     FROM tab_score
     WHERE cou_id=1) score1,
    (SELECT stu_id,
            sco_score
     FROM tab_score
     WHERE cou_id=2) score2
WHERE score1.stu_id=score2.stu_id
      AND
      score1.sco_score>score2.sco_score;


-- 2、查询平均成绩大于60分的同学的学号和平均成绩
/*
思路:
1、在成绩表中根据学号进行分组
2、求出每个学号对应的平均分
3、选出平均分大于60的学生
*/
SELECT stu_id 学号,
       AVG(sco_score) 平均分
FROM tab_score
GROUP BY stu_id
HAVING AVG(sco_score)>60;

-- 3、查询所有学生的学号、姓名、选课数、总成绩
/*
思路:
1、将学生表中的全部信息与成绩表中的全部信息汇总为一张表,保持学生表的完整性,借助学生id清洗数据
2、利用学生id的唯一性进行分组,每组的课程id总数正好为选课数,分数总数正好为总分数
*/
SELECT stu.stu_id 学号,
       stu.stu_name 姓名,
       COUNT(sco.cou_id) 选课数 ,
       SUM(sco.sco_score) 总成绩
FROM (tab_student stu LEFT JOIN tab_score sco
      ON stu.stu_id=sco.stu_id)
GROUP BY stu.stu_id;


-- 4、查询姓“卫”的老师的个数
/*
思路:
使用模糊查询,查询姓名第一个字是卫的老师,名字的总长不定因此应该使用%
*/
SELECT COUNT(tea_name) 卫姓老师总数
FROM tab_teacher
WHERE tea_name LIKE '卫%';

-- 5、查询没学过“褚一”老师课程的同学的学号、姓名
/*
思路:
1、找出褚一老师的教师id
2、根据教师id寻找褚一老师所教的课程id
3、将学生根据学号进行分组
4、找出分组后学生课程号组成的集合中不包含褚一老师课程的学生id
5、根据学生id在学生表中寻找数据
*/
SELECT stu_id 学号,
         stu_name 姓名
FROM tab_student
WHERE stu_id IN
    (SELECT stu_id
    FROM 
        (SELECT stu_id,
         cou_id
        FROM tab_score
        GROUP BY  stu_id
        HAVING (
            (SELECT cou_id
            FROM tab_course
            WHERE tea_id= 
                (SELECT tea_id
                FROM tab_teacher
                WHERE tea_name='褚一'))) NOT IN (cou_id)) student);


-- 6、查询学过课程号1和学习过课程号2的同学的学号、姓名
/*
思路:
1、分别查出课程id为1以及课程id为2的课程,并做笛卡尔积
2、两张表中学号一致的列为同时学习id为1以及id为2课程的学生
3、根据步骤二查询出的学号在学生表中找出对应学生
*/
SELECT stu_id 学号,
       stu_name 姓名
FROM tab_student
WHERE stu_id IN
    (SELECT score1.stu_id
    FROM 
        (SELECT *
        FROM tab_score
        WHERE cou_id=1) score1, 
        (SELECT *
        FROM tab_score
        WHERE cou_id=2) score2
        WHERE score1.stu_id=score2.stu_id); 

-- 7、查询学过“褚一”老师课程的同学的学号、姓名
/*
思路:
先找到褚一老师的教师id
根据教师id找到褚一老师的所教课程id
根据课程id在成绩表找到选择该课程的学生学号
最后根据学生学号在学生表中找到对应学生
*/
SELECT stu_id 学生学号,
       stu_name 学生姓名
FROM tab_student
WHERE stu_id IN
    (SELECT stu_id
    FROM tab_score
    WHERE cou_id=
        (SELECT cou_id
         FROM tab_course
         WHERE tea_id=
            (SELECT tea_id
            FROM tab_teacher
            WHERE tea_name='褚一')));

-- 8、查询课程号2的成绩比课程号1的成绩低的所有同学的学号、姓名
/*
思路:
1、分别查出课程id为1以及课程id为2的课程,并做笛卡尔积
2、根据要求制定条件,找出学号相同且课程2的分数低于课程1的分数的同学
*/
SELECT stu_id,
         stu_name
FROM tab_student
WHERE stu_id IN
    (SELECT score1.stu_id FROM
        (SELECT *
        FROM tab_score
        WHERE cou_id=1) score1, 
            (SELECT *
            FROM tab_score
            WHERE cou_id=2) score2
            WHERE score2.sco_score<score1.sco_score
                    AND score1.stu_id=score2.stu_id);

-- 9、查询所有课程成绩小于60分的同学的学号、姓名
/*
思路:
最大分数小于60的同学其他分数一定小于60
*/
SELECT tab_student.stu_id 学号,
         stu_name 姓名
FROM tab_student,
    (SELECT stu_id,
         MAX(sco_score)
    FROM tab_score
    GROUP BY  stu_id
    HAVING MAX(sco_score)<60) student1
WHERE student1.stu_id=tab_student.stu_id;
 
-- 10、查询没有学全所有课的同学的学号、姓名
/*
先查看所有的课程一共有多少门
根据学号分组,查看学生的选课总数是否等于课程总数
*/
SELECT stu_id 学号,
         stu_name 姓名
FROM tab_student
WHERE stu_id IN
    (SELECT stu_id
    FROM tab_score
    GROUP BY stu_id
    HAVING COUNT(cou_id)!=(SELECT COUNT(*)
                           FROM tab_course));
posted @ 2021-05-23 18:16  张知非  阅读(162)  评论(0编辑  收藏  举报