• MySQL 之 SQL练习


    SQL练习

    本文是针对SQL的练习,练完这几十道题,会对SQL的理解更深,写SQL的能力也会更强
    本文的思路或者答案或者理解是错的
    欢迎讨论和纠正

    练习前准备

    创建表以及添加基础的表数据

    CREATE DATABASE stumsc;
    CREATE TABLE student(
    	sno VARCHAR(10) PRIMARY KEY,
    	sname VARCHAR(20),
    	sage INT,
    	ssex VARCHAR(5)
    );
    CREATE TABLE teacher(
    	tno VARCHAR(10) PRIMARY KEY,
    	tname VARCHAR(20)
    );
    CREATE TABLE course(
    	cno VARCHAR(10),
    	cname VARCHAR(20),
    	tno VARCHAR(20),
    	PRIMARY KEY (cno,tno)
    );
    CREATE TABLE sc(
    	sno VARCHAR(10),
    	cno VARCHAR(10),
    	score DOUBLE(4,2),
    	PRIMARY KEY (sno,cno)
    );
    /*******初始化学生表的数据******/
    INSERT INTO student VALUES ('s001','张三',23,'男');
    INSERT INTO student VALUES ('s002','李四',23,'男');
    INSERT INTO student VALUES ('s003','吴鹏',25,'男');
    INSERT INTO student VALUES ('s004','琴沁',20,'女');
    INSERT INTO student VALUES ('s005','王丽',20,'女');
    INSERT INTO student VALUES ('s006','李波',21,'男');
    INSERT INTO student VALUES ('s007','刘玉',21,'男');
    INSERT INTO student VALUES ('s008','萧蓉',21,'女');
    INSERT INTO student VALUES ('s009','陈萧晓',23,'女');
    INSERT INTO student VALUES ('s010','陈美',22,'女');
    COMMIT;
    /******************初始化教师表***********************/
    INSERT INTO teacher VALUES ('t001', '刘阳');
    INSERT INTO teacher VALUES ('t002', '谌燕');
    INSERT INTO teacher VALUES ('t003', '胡明星');
    COMMIT;
    /***************初始化课程表****************************/
    INSERT INTO course VALUES ('c001','J2SE','t002');
    INSERT INTO course VALUES ('c002','Java Web','t002');
    INSERT INTO course VALUES ('c003','SSH','t001');
    INSERT INTO course VALUES ('c004','Oracle','t001');
    INSERT INTO course VALUES ('c005','SQL SERVER 2005','t003');
    INSERT INTO course VALUES ('c006','C#','t003');
    INSERT INTO course VALUES ('c007','JavaScript','t002');
    INSERT INTO course VALUES ('c008','DIV+CSS','t001');
    INSERT INTO course VALUES ('c009','PHP','t003');
    INSERT INTO course VALUES ('c010','EJB3.0','t002');
    COMMIT;
    /***************初始化成绩表***********************/
    INSERT INTO sc VALUES ('s001','c001',78.9);
    INSERT INTO sc VALUES ('s002','c001',80.9);
    INSERT INTO sc VALUES ('s003','c001',81.9);
    INSERT INTO sc VALUES ('s004','c001',60.9);
    INSERT INTO sc VALUES ('s001','c002',82.9);
    INSERT INTO sc VALUES ('s002','c002',72.9);
    INSERT INTO sc VALUES ('s003','c002',81.9);
    INSERT INTO sc VALUES ('s001','c003',59.0);
    COMMIT;
    

    SQL 练习题及答案

    -- 查询学生表所有信息
    SELECT * FROM student;
    -- 查询教师表所有信息
    SELECT * FROM teacher;
    -- 查询课程表的所有信息
    SELECT * FROM course;
    -- 查询成绩表的所有信息
    SELECT * FROM sc;
    
    -- 查询出 相同姓名学生的学号和名字
    select s1.sno,s1.sname  from student s1 where s1.sname IN (
    select  s1.sname from student s1 JOIN student s2 on s1.sno = s2.sno and s1.sname = s2.sname group by s1.sname HAVING COUNT(1) > 1 )
    
    -- 查询所有学生的学号、姓名、选课数
    select s.sno,s.sname,COUNT(1) '选课数' from student s left join sc  sc on s.sno =sc.sno group by s.sno
    
    -- 查询各科成绩最高分,以以下形式显示:课程号,课程名、最高分,最低分
    select c.cno,c.cname,MAX(sc.score),MIN(sc.score) from course c join sc sc on c.cno = sc.cno   GROUP BY c.cno,c.cname
    
    -- 1、查询“c001”课程比“c002”课程成绩高的所有学生的学号;
    SELECT s1.sno FROM sc s1 LEFT JOIN sc s2 ON s1.sno = s2.sno AND s1.cno = 'c001' AND s2.cno='c002' WHERE s1.score>s2.score
    -- 2、查询平均成绩大于60 分的同学的学号和平均成绩;
    SELECT sno ,AVG(IFNULL(score,0)) '平均成绩' FROM sc GROUP BY sno HAVING  AVG(IFNULL(score,0))>60  
    
    -- 2、查询平均成绩大于60 分的同学的学号和平均成绩 并按照成绩降序排列 
    -- DESC降序   ASC 升序
    SELECT sno ,AVG(IFNULL(score,0)) '平均成绩' FROM sc GROUP BY sno HAVING  AVG(IFNULL(score,0))>60  ORDER BY  AVG(IFNULL(score,0))  DESC
    
    -- 3、查询所有同学的学号、姓名、选课数、总成绩;
    SELECT s.sno,sname,COUNT(cno) '选课数',SUM(IFNULL(score,0)) '总成绩' FROM student s LEFT JOIN sc ON s.sno = sc.sno GROUP BY sno;
    
    SELECT s.sno,s.sname,IFNULL(s2.c,0),IFNULL(s2.s,0) FROM student s LEFT JOIN 
    (SELECT sno,COUNT(1) c,SUM(IFNULL(score,0)) s 
    FROM sc GROUP BY sno) s2 ON s.sno=s2.sno
    -- 4、查询姓“刘”的老师的个数
    SELECT COUNT(1) '个数' FROM teacher WHERE tname like '刘%'
    
    -- 5、查询没学过“谌燕”老师课的同学的学号、姓名;
    SELECT s.sno,s.sname FROM student  s WHERE  s.sno NOT IN
    (SELECT DISTINCT sc.sno FROM teacher t  JOIN course c ON t.tname='谌燕' AND  t.tno = c.tno JOIN sc ON c.cno = sc.cno)
    
    -- 6、查询学过“c001”并且也学过编号“c002”课程的同学的学号、姓名;
     
    SELECT s.sno,s.sname FROM student s WHERE s.sno IN
    (SELECT s1.sno FROM sc s1 JOIN sc s2  ON s1.sno = s2.sno AND s1.cno='c001' AND s2.cno = 'c002' ) #子查询实现
    
    SELECT s.sno, s.sname FROM student s JOIN sc s1 ON s.sno = s1.sno JOIN sc s2 ON s2.sno = s1.sno AND s1.cno='c001' AND s2.cno = 'c002' 
    
    -- 7、查询学过“谌燕”老师所教的所有课的同学的学号、姓名;
    
    
    SELECT sc.* FROM sc sc  WHERE sc.cno IN (
    SELECT cno FROM teacher t1 JOIN course c1 ON t1.tname='谌燕' AND t1.tno=c1.tno)
    GROUP BY sno HAVING COUNT(1)=
    (SELECT COUNT(1) FROM teacher t1 JOIN course c1 ON t1.tname='谌燕' AND t1.tno=c1.tno)
    
    -- 8、查询课程编号“c002”的成绩比课程编号“c001”课程低的所有同学的学号、姓名;
    
    SELECT s.sno,s.sname FROM student s LEFT JOIN sc s1 ON s.sno = s1.sno  AND s1.cno = 'c001'
    	LEFT JOIN sc s2 ON s1.sno = s2.sno  AND s2.cno = 'c002'  WHERE s1.score > s2.score
    
    -- 9、查询所有课程成绩小于60 分的同学的学号、姓名;
    SELECT sno,sname FROM student WHERE sno NOT IN
    (SELECT DISTINCT sno FROM sc WHERE score >= 60 )
    
    -- 10、查询没有学全所有课的同学的学号、姓名;
    -- 先查出所有课程数
    SELECT sno,sname FROM student WHERE sno NOT IN (
    SELECT sno FROM sc GROUP BY sno HAVING COUNT(1) = (SELECT COUNT(1) FROM course ))
    
    -- 11、查询至少有一门课与学号为“s001”的同学所学相同的同学的学号和姓名;
    #找出s001这个同学学习的课程
    SELECT DISTINCT s.sno,s.sname FROM student  s JOIN sc sc ON s.sno = sc.sno WHERE sc.cno IN (
    SELECT cno FROM sc WHERE sno = 's001'
    ) AND s.sno != 's001'
    
    -- 12、查询至少学过学号为“s001”同学所有一门课的其他同学学号和姓名;
    
    
    -- 13、把“SC”表中“谌燕”老师教的课的成绩都更改为此课程的平均成绩;
    #先查出平均成绩
    UPDATE sc,(SELECT sc.cno,AVG(sc.score) av FROM teacher t JOIN course c ON t.tno = c.tno JOIN sc sc ON c.cno = sc.cno where t.tname = '谌燕' GROUP BY sc.cno ) sc2 SET sc.score = sc2.av WHERE sc.cno = sc2.cno 
    
    SELECT * from sc
    
    -- 14、查询和“s001”号的同学学习的课程完全相同的其他同学学号和姓名;
    #s001 的课程数 在切除没有选s001中的 在在选了之中剔除 再利用选科数筛选
    
    select sno from sc where sno not in(
    (select sno from sc where cno not  in(
    select cno from sc where sno='s001'))) and sno!='s001'
    group by sno having 
    count(1)=(select count(1) FROM sc WHERE sno='s001')
    
    -- 15、删除学习“谌燕”老师课的SC 表记录;
    delete from sc WHERE cno IN (
    SELECT c.cno FROM teacher t JOIN course c ON t.tno = c.tno where t.tname = '谌燕'
    )
    
    -- 17、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
    SELECT cno,MAX(score),MIN(score) from sc GROUP BY cno
    
    -- 18、按各科平均成绩从低到高和及格率的百分数从高到低顺序
    SELECT cno,AVG(score) '平均分',SUM(CASE WHEN score>=60 THEN	1 ELSE	0 END)/COUNT(1) '及格率' FROM sc GROUP BY cno  ORDER BY 2,3 DESC 
    
    -- 19、查询不同老师所教不同课程平均分从高到低显示 
    SELECT t.tname,sc.cno,AVG(score) '平均分',SUM(CASE WHEN score>=60 THEN	1 ELSE	0 END)/COUNT(1) '及格率' FROM  teacher t  JOIN course c ON t.tno = c.tno  JOIN sc sc ON c.cno = sc.cno 
    GROUP BY tname,cno ORDER BY 3,4 DESC
    
    -- 20、统计列印各科成绩,各分数段人数:课程ID,课程名称,[100-85],[85-70],[70-60],[ <60]
    SELECT c.cno,c.cname,SUM(CASE WHEN score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) '[100-85]',
    SUM(CASE WHEN score BETWEEN 70 AND 85 THEN 1 ELSE 0 END) '[85-70]',
    SUM(CASE WHEN score BETWEEN 60 AND 70 THEN 1 ELSE 0 END) '[70-60]',
    SUM(CASE WHEN score <60 THEN 1 ELSE 0 END) '[<60]'
    FROM course c LEFT JOIN sc ON c.cno = sc.cno GROUP BY c.cno,c.cname
    
    -- 21、查询各科成绩前三名的记录:(不考虑成绩并列情况)
    SELECT s1.cno,s1.score FROM sc s1 WHERE 
    (SELECT COUNT(1) from sc s2 where s1.cno = s2.cno AND s2.score > s1.score)<3
    ORDER BY s1.cno,s1.score DESC
    
    -- 22、查询每门课程被选修的学生数
    SELECT c1.cno,c1.cname,IFNULL(c2.c,0) FROM course c1 LEFT JOIN
    (SELECT cno,COUNT(1) c FROM sc GROUP BY cno) c2 ON c1.cno = c2.cno
    
    -- 23、查询出只选修了一门课程的全部学生的学号和姓名
    #子查询
    select s.sno,s.sname from student s WHERE sno in (
    select sno FROM sc  GROUP BY sno HAVING COUNT(1)=1 )
    #连接查询
    select s.sno,s.sname from student s JOIN sc sc ON s.sno = sc.sno 
    GROUP BY s.sno HAVING COUNT(1) =1
    
    -- 24、查询男生、女生人数
    SELECT ssex,COUNT(1) FROM student GROUP BY ssex
    
    -- 25、查询姓“张”的学生名单
    SELECT sname FROM student WHERE sname LIKE  '张%'
    
    -- 26、查询同名同性学生名单,并统计同名人数
    SELECT sname,ssex,COUNT(1) FROM student GROUP BY sname,ssex
    
    -- 28、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列
    #默认ASC从小到大 升序 DESC 从大到小降序
    SELECT cno,AVG(score) FROM sc GROUP BY cno ORDER BY  AVG(score) ASC,cno DESC
    
    -- 29、查询平均成绩大于85 的所有学生的学号、姓名和平均成绩
    SELECT s.sno,sc.cno,s.sname,AVG(score) FROM student s JOIN sc sc ON s.sno = sc.sno 
    GROUP BY  s.sno,sc.cno HAVING AVG(score) >85
    SELECT cno,AVG(score),s.sname FROM student s JOIN sc ON s.sno=sc.sno 
    GROUP BY cno,s.sname HAVING AVG(score)>85
    
    -- 30、查询课程名称为“数据库”,且分数低于60 的学生姓名和分数
    SELECT s.sno,s.sname,score FROM course c JOIN sc ON c.cno=sc.cno AND 
    c.cname='数据库' AND score<60
    JOIN student s ON sc.sno=s.sno
    -- 31、查询所有学生的选课情况;统计
    SELECT s.sno,s.sname,COUNT(sc.sno) FROM student s LEFT JOIN sc sc
    ON s.sno = sc.sno GROUP BY s.sno
    
    -- 32、查询任何一门课程成绩在70 分以上的姓名、课程名称和分数;
    SELECT s.sno,s.sname,c.cname,sc.score FROM student s JOIN sc sc ON s.sno = sc.sno AND sc.score >=70 
    JOIN course c ON sc.cno = c.cno WHERE s.sno NOT IN 
    (SELECT sno FROM sc WHERE score <70)
    
    SELECT a.sno,a.sname,c.cname,sc.score FROM 
    (SELECT s.sno,s.sname FROM student s WHERE s.sno NOT IN(
    SELECT sno FROM sc WHERE sc.`score`<70)) a JOIN sc ON a.sno=sc.sno 
    JOIN course c ON sc.cno=c.cno
    
    -- 33、查询不及格的课程,并按课程号从大到小排列
    SELECT sc.* FROM sc WHERE score<60 ORDER BY sno,cno DESC
    
    -- 34、查询课程编号为c001 且课程成绩在80 分以上的学生的学号和姓名;
    SELECT s.sno,s.sname FROM sc sc JOIN student s ON sc.sno = s.sno AND sc.cno='c001' 
    WHERE sc.score >=80
    
    -- 35、求选了课程的学生人数
    SELECT COUNT(a.sno) FROM( 
    SELECT DISTINCT sno FROM sc) a
    
    -- 36、查询选修“谌燕”老师所授课程的学生中,成绩最高的学生姓名及其成绩
    SELECT s.sno,s.sname,a.m FROM student s JOIN sc sc ON s.sno = sc.sno JOIN
    (SELECT sc.cno,MAX(score) m FROM teacher t JOIN course c ON t.tno = c.tno AND t.tname = '谌燕'
    JOIN sc sc ON c.cno = sc.cno GROUP BY sc.cno ) a ON sc.cno = a.cno AND a.m = sc.score
    
    -- 37、查询各个课程及相应的选修人数
    SELECT c.cname,COUNT(sc.cno) FROM course c LEFT JOIN sc ON c.cno = sc.cno GROUP BY c.cname
    
    SELECT c.cno,COUNT(sc.cno) FROM course c LEFT JOIN sc ON c.cno=sc.cno GROUP BY c.cno
    -- 38、查询不同课程成绩相同的学生的学号、课程号、学生成绩
    # 不同课程
    SELECT sc1.sno,sc1.cno,sc1.score FROM sc sc1 JOIN sc sc2 ON 
    sc1.sno =sc2.sno AND sc1.score =sc2.score AND sc1.cno != sc2.cno
    
    -- 39、查询每门功课成绩最好的前两名
    SELECT sc1.sno,sc1.cno,sc1.score FROM sc sc1 WHERE (
    SELECT COUNT(1) FROM sc sc2 WHERE sc1.cno=sc2.cno AND sc1.score<sc2.score
    )<2 GROUP BY sc1.sno,sc1.cno ORDER BY sc1.cno,sc1.score DESC
    
    -- 40、统计每门课程的学生选修人数(超过10 人的课程才统计)。
    -- 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
    SELECT cno,COUNT(cno)  c FROM sc GROUP BY cno HAVING c >10 ORDER BY c DESC, cno ASC
    
    -- 41、检索至少选修两门课程的学生学号
    SELECT sno from sc GROUP BY sno HAVING COUNT(cno) >=2
    -- 42、查询全部学生都选修的课程的课程号和课程名
    #每门课程选的人数
    SELECT cno,COUNT(cno) FROM sc GROUP BY cno;
    #所有学生树
    SELECT COUNT(1) FROM student
    #每人选课数
    SELECT sno,COUNT(sno) FROM sc GROUP BY sno; 
    SELECT * from sc;
    
    SELECT cno,cname FROM course where cno IN(
    SELECT sc.cno FROM sc sc  GROUP BY sc.cno
    HAVING COUNT(cno) = (SELECT COUNT(*) FROM student)
    )
    
    -- 43、查询没学过“谌燕”老师讲授的任一门课程的学生姓名
    SELECT sname FROM student WHERE sno NOT IN
    (SELECT DISTINCT s.sno FROM student s JOIN sc sc ON s.sno = sc.sno WHERE sc.cno  IN (
    SELECT cno FROM teacher t JOIN course c ON t.tno = c.tno AND  t.tname = '谌燕'
    ))
    
    -- 44、查询两门及以上不及格课程的同学的学号及其平均成绩
    SELECT sno,AVG(score) FROM sc  WHERE sno IN(
    SELECT sno FROM sc WHERE score <60 GROUP BY sc.sno HAVING COUNT(cno)>=2
    ) GROUP BY sno
    
    -- 45、检索“c004”课程分数小于60,按分数降序排列的同学学号
    SELECT sno,score FROM sc WHERE cno='c004' AND score <60 ORDER BY score DESC
    
    -- 46、删除“s002”同学的“c001”课程的成绩
    DELETE FROM sc WHERE sno='s002' AND cno = 'c001'
    
  • 相关阅读:
    pandas--对axis=0,axis=1的理解
    启动secondarynamenode时报错
    5月27日经历问题(在有框架的情况下从无到有增加一套功能)
    5.21工作记录(修改页面跳转,去掉多余的js;增加图片清除功能)
    工作记录520
    5月14日经历问题
    idea快捷键
    Linux下常用redis指令
    初识lunix
    Redis
  • 原文地址:https://www.cnblogs.com/zero-vic/p/14252232.html
Copyright © 2020-2023  润新知