相信大多学习了 Mysql 数据库语言的同学都会上网找练习来练手,而大部分的人肯定知道有一篇 Mysql 经典练习题50题的帖子,上面的题目基本上涵盖了 Mysql 查询语句的关键知识点。
笔者Peter近期对又将这 50 题进行了练习,同时整理了相关的参考答案,有自己的思路和方法,也有参考大神们的。不得不说,这50题对SQL的提升真的很有帮助!
笔者使用的 MySQL 版本 是 MySQL 5.7.28
。
鉴于 50 题篇幅太长,本文只展示了第10题及笔者的思考,50 题完整版练习题以及笔者的答案实践已整理在pdf文件中,共有100多页,在文末提供获取的方法。
题目10
题目需求
查询学过01课程,但是没有学过02课程的学生信息(注意和上面????题目的区别)
SQL实现
首先看看哪些同学是满足要求的:只有06号同学是满足的
错误思路1
直接将上面一题的结果全部排出,导致那些没有学过01课程的学生也出现了:07,08
select s1.*
from Student s1
where s_id not in ( -- 直接将上面一题的结果全部排出,导致那些没有学过01课程的学生也出现了:07,08select s2.s_id from Score s2join Score s3on s2.s_id=s3.s_idwhere s2.c_id='01' and s3.c_id ='02'
);
错误思路2
将上面题目中的02课程直接取反,导致同时修过01,02,03或者只修01,03的同学也会出现
select s1.*
from Student s1
where s_id in (select s2.s_id from Score s2join Score s3on s2.s_id=s3.s_idwhere s2.c_id='01' and s3.c_id !='02' -- 直接取反是不行的,因为修改(01,02,03)的同学也会出现
);
正确思路
https://www.jianshu.com/p/9abffdd334fa
-- 方法1:根据两种修课情况来判断select s1.*
from Student s1
where s1.s_id in (select s_id from Score where c_id='01') -- 修过01课程,要保留
and s1.s_id not in (select s_id from Score where c_id='02'); -- 哪些人修过02,需要排除
!!!!!方法2:先把06号学生找出来
select * from Student where s_id in (select s_id from Score where c_id='01' -- 修过01课程的学号and s_id not in (select s_id -- 同时学号不能在修过02课程中出现from Score where c_id='02')
);
50道题的标题整理如下:
完整版PDF下载
为方便大家练习,可以在公号「柠檬数据」后台回复 “SQL50”获取完整的MySQL经典50题及笔者实践的答案。
????长按上方二维码 2 秒
回复「SQL50」即可获取资料