精华内容
下载资源
问答
  • sql50题
    千次阅读 多人点赞
    2018-03-28 00:04:03

    首先必须要吐槽一下,网上流传的sql50题!!!

    类似下面

    Course(C#,Cname,T#) 课程表

    CREATE TABLE course (

      cid varchar(10) NOT NULL,

      cName varchar(10) DEFAULT NULL,

      tid int(20) DEFAULT NULL,

      PRIMARY KEY (cid)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    通过上面的表创建语句可以看出,在course表中的字段有cid,cName,tid这三个字段,但是网上流传的经典sql50题中,在做查询的时候竟然使用C#以及T#等等这些在表中根本就不存在的字段进行查询,也是醉了~~~

    对于Course(C#,Cname,T#) ,我的理解是对表中字段的解释,例如C#代表,表Course中的字段cid,并且是主键,若在查询的时候使用C#,就会报错,因为C#在表Course中根本不存在!!!

    所以还是自己整理吧~~~~

    sql50题会逐步更新~~



    创建表语句

    表student:

    CREATE TABLE `student` (
      `sid` varchar(10) NOT NULL,
      `sName` varchar(20) DEFAULT NULL,
      `sAge` datetime DEFAULT '1980-10-12 23:12:36',
      `sSex` varchar(10) DEFAULT NULL,
      PRIMARY KEY (`sid`)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    表teacher:

    CREATE TABLE `teacher` (
      `tid` int(10) DEFAULT NULL,
      `tName` varchar(10) DEFAULT NULL

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    课程表course:

    CREATE TABLE `course` (
      `cid` varchar(10) NOT NULL,
      `cName` varchar(10) DEFAULT NULL,
      `tid` int(20) DEFAULT NULL,
      PRIMARY KEY (`cid`)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    成绩表sc:

    CREATE TABLE `sc` (
      `sid` varchar(10) DEFAULT NULL,
      `cid` varchar(10) DEFAULT NULL,
      `score` int(10) DEFAULT NULL

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    插入数据:

    INSERT INTO `teacher` (`tid`, `tName`) VALUES ('1', '田青风');
    INSERT INTO `teacher` (`tid`, `tName`) VALUES ('2', '赵德林');
    INSERT INTO `teacher` (`tid`, `tName`) VALUES ('3', '马老师');


    INSERT INTO `test`.`student` (`sid`, `sName`, `sAge`, `sSex`) VALUES ('1', '张三丰', '17', '男');
    INSERT INTO `test`.`student` (`sid`, `sName`, `sAge`, `sSex`) VALUES ('2', '张无极', '18', '男');
    INSERT INTO `test`.`student` (`sid`, `sName`, `sAge`, `sSex`) VALUES ('3', '李奎', '19', '女');
    INSERT INTO `test`.`student` (`sid`, `sName`, `sAge`, `sSex`) VALUES ('4', '李元宝', '20', '女');


    INSERT INTO `sc` (`sid`, `cid`, `score`) VALUES ('1', '001', '80');
    INSERT INTO `sc` (`sid`, `cid`, `score`) VALUES ('1', '002', '60');
    INSERT INTO `sc` (`sid`, `cid`, `score`) VALUES ('1', '003', '75');
    INSERT INTO `sc` (`sid`, `cid`, `score`) VALUES ('2', '001', '85');
    INSERT INTO `sc` (`sid`, `cid`, `score`) VALUES ('2', '002', '70');
    INSERT INTO `sc` (`sid`, `cid`, `score`) VALUES ('3', '004', '100');
    INSERT INTO `sc` (`sid`, `cid`, `score`) VALUES ('3', '001', '90');
    INSERT INTO `sc` (`sid`, `cid`, `score`) VALUES ('3', '002', '55');
    INSERT INTO `sc` (`sid`, `cid`, `score`) VALUES ('4', '002', '65');
    INSERT INTO `sc` (`sid`, `cid`, `score`) VALUES ('4', '003', '60');


    INSERT INTO `course` (`cid`, `cName`, `tid`) VALUES ('001', '企业管理', '3');
    INSERT INTO `course` (`cid`, `cName`, `tid`) VALUES ('002', '马克思', '3');
    INSERT INTO `course` (`cid`, `cName`, `tid`) VALUES ('003', 'UML', '2');
    INSERT INTO `course` (`cid`, `cName`, `tid`) VALUES ('004', '数据库', '1');

    INSERT INTO `course` (`cid`, `cName`, `tid`) VALUES ('005', '英语', '1');


    练习:

    1.查询“某1”课程比“某2”课程成绩高的所有学生的学号;

    #课程001的所有学生和成绩
    (select sid,score from sc where cid = '001') a
    #课程002的所有学生和成绩
    (select sid,score from sc where cid = '002') b

    #查询的条件(针对的是同一个学生)
    where a.score > b.score AND a.sid = b.sid

    #查询的是课程001比002分数高的所有学生的编号
    SELECT a.sid

    #整个的查询语句

    SELECT a.sid from (SELECT sid,score from sc where sc.cid ='001') a,(SELECT sid,score from sc where sc.cid = '002') b where a.score > b.score AND a.sid = b.sid;

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

    #查询条件:平均成绩大于60分,但需要根据学号进行分组
    GROUP BY sid HAVING avg(score) > 60 
    #查询的是满足条件的所有学生的学号和平均成绩
    SELECT sid,avg(score) from sc

    #整个查询语句

    SELECT sid,avg(score) from sc GROUP BY sid HAVING avg(score) > 60

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

    #两表关联的查询,涉及到的表有student,sc

    SELECT s.sid,s.sName,COUNT(sc.cid),SUM(sc.score) from student s LEFT OUTER JOIN sc on s.sid = sc.sid GROUP BY s.sid

    4.查询姓“李”的老师的个数;

    #模糊查询

    select COUNT(0) from teacher where tName LIKE '李%'

    5.查询没学过“叶平”老师课的同学的学号、姓名;
    #涉及到的是三表关联,查询田青风老师的学生

    SELECT DISTINCT(sc.sid ) from sc,course,teacher where course.tid=teacher.tid and course.cid=sc.cid AND teacher.tName ='田青风'

    #查询学生表中不是田青风老师的学生

    SELECT student.sid,student.sName from student where sid not in(。。。)

    #整条sql语句

    SELECT student.sid,student.sName from student where sid not in(SELECT DISTINCT(sc.sid ) from sc,course,teacher where course.tid=teacher.tid and course.cid=sc.cid AND teacher.tName ='田青风')

    6.查询学过“企业管理”并且也学过编号“数据库”课程的同学的学号、姓名;
    #查询课程“企业管理”的所有学生和编号
    select student.sid,student.sName from student,course,sc where cName='企业管理' and student.sid=sc.sid and course.cid=sc.cid

    #查询课程“数据库”所有学生和编号
    select student.sid,student.sName from student,course,sc where cName="数据库" and student.sid=sc.sid and course.cid=sc.cid

    #整条查询语句

    select a.sid,a.Sname from (select student.sid,student.sName from student,course,sc where cName='企业管理' and student.sid=sc.sid and course.cid=sc.cid) a,(select student.sid,student.sName from student,course,sc where cName="数据库" and student.sid=sc.sid and course.cid=sc.cid) b where a.sid=b.sid


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

    #查询课程企业管理的所有同学的学号,姓名

    select student.sid,student.sName from student,sc,course where sc.cid='001' and student.sid=sc.sid and sc.cid=course.cid


    #查询课程UML的所有同学的学号,姓名
    select student.sid,student.sName FROM student,sc,course where sc.cid='002' AND student.sid=sc.sid and sc.cid=course.cid

    #整条查询语句 
    select a.sid,a.sName from (select student.sid,student.sName,sc.score from student,sc where student.sid=sc.sid AND sc.cid = '001'

    ) a,(select student.sid,student.sName,sc.score FROM student,sc where student.sid=sc.sid AND sc.cid= '002') b where a.score > b.score and a.sid = b.sid


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

    #这条语句就稍微复杂一点,语句中有两个条件,是对查询结果的再次筛选,主要是为了满足“老师所教的所有课”

    SELECT sid,sName from student where sid in(SELECT sid from course,sc,teacher where teacher.tName ='田青风' and course.cid=sc.cid and course.tid=teacher.tid GROUP BY sid HAVING COUNT(sc.cid)=(SELECT count(cid) from course,teacher where teacher.tName='田青风' and teacher.tid=course.tid))


    9.查询所有课程成绩小于分的同学的学号、姓名;

    select sid,sName from student WHERE sid not in(SELECT student.sid from student,sc where student.sid=sc.sid and sc.score>90);


    10.查询没有学全所有课的同学的学号、姓名

    select sid,sName from student where sid not in (select student.sid from student,sc WHERE student.sid=sc.sid GROUP BY student.sid HAVING COUNT(sc.cid) < 5)

    更多相关内容
  • sql 50题

    2021-01-19 22:01:08
    sql50题,从头到尾练了一遍,收获很大,也对sql有更深一步认识,其中有些代码不是最优方案,还需要进一步完善。 文章是在知乎 https://zhuanlan.zhihu.com/p/43289968 看到的,觉得不错,就一点一点跟着练了练,其实...
  • /* create database test50; use test50; create table Student(sid varchar(10),sname varchar(10),sage datetime,ssex nvarchar(10)); insert into Student values(‘01’ , ‘赵雷’ , ‘1990-01-01’ , ‘男’);...
  • SQL50题中选取以下编号题目:1、4、7、8、9、10、11、14、15、16、33、35、36、42  1.查询” 01 “课程比” 02 “课程成绩高的学生的信息及课程分数  查询同时存在”01″课程和”02″课程的情况 SELECT student....
  • SQL查询50题

    2017-08-23 11:28:03
    在网上找了好多sql练习(包含答案)最后发现这个更好为了自己方便找所有上传这个资源
  • sql 50道 练习

    千次阅读 2022-03-17 15:18:09
    sql 练习题目,学生教师分数表
    • 打基础
    • sql50题目
    • 经典6题

    一个月的时间,看了视频,做了sql 经典的50 题目
    参考文档:https://blog.csdn.net/paul0127/article/details/82529216?
    https://www.jianshu.com/p/476b52ee4f1b
    虽然存在不会的题目,排序类19题。
    从不懂到渐渐熟悉,慢慢了解,发现sql 的简洁强大易懂简洁!
    感谢hchc的鼓励,
    慢慢来,沉稳的写程序 ~~

    一:打基础
    (一):select 输入语句
    在这里插入图片描述
    (二):group by
    ①:group by 与 distinct (去重)很像
    在这里插入图片描述

    group by 之后
    

    在这里插入图片描述
    ②:聚合函数sum(), avg() 一定和group by 搭配
    结果为一条记录
    如果没有聚合函数,则返回 每组 的 第一条

    ③:having 后加
    常数 , 聚合函数sum() , group by 后指定的列名

    ④:group_concat , 分组连在一起
    concat():行分组连在一起
    在这里插入图片描述

    (三):多个表join 之后,非常好筛选
    在这里插入图片描述
    在这里插入图片描述

    添加筛选条件
    

    在这里插入图片描述
    (四)order by 排序

    //查询结果按人数降序排列,若人数相同,按课程号升序排列
    order by count(sid) desc, sc.cid asc
    

    (五):按照某个部门cid,分组
    ①:外部的 group by 应用于整个结果
    ②:内部的group by 应用于 每条 cid

    在这里插入图片描述

    (六):语句特点
    注释: – 空格
    不区分 大小写


    二:开始解题

    1:查询" 01 “课程比” 02 "课程成绩高的学生的信息及课程分数
    在这里插入图片描述
    1.1:在这里插入图片描述
    1.2:

    在这里插入图片描述

    1.3
    在这里插入图片描述
    2:查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩

    在这里插入图片描述

    3:查询在 SC 表存在成绩的学生信息

    在这里插入图片描述
    (下面解法,结果不是很想要的)
    在这里插入图片描述
    4:查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
    sum ,count, avg 一般要 group by

    在这里插入图片描述
    4.1 查有成绩的学生信息

    在这里插入图片描述
    5:查询「李」姓老师的数量

    在这里插入图片描述
    6:查询学过「张三」老师授课的同学的信息

    在这里插入图片描述
    在这里插入图片描述

    7: 查询没有学全所有课程的同学的信息

    在这里插入图片描述

    8:查询和" 01 "号的同学学习的课程完全相同的其他同学的信息

    在这里插入图片描述
    10: 查询没学过"张三"老师讲授的任一门课程的学生姓名

    在这里插入图片描述
    11:查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩

    (解法一)
    在这里插入图片描述

    (解法二)在这里插入图片描述
    12: 检索" 01 "课程分数小于 60,按分数降序排列的学生信息

    在这里插入图片描述
    13:按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
    case : 行转列

    在这里插入图片描述
    14: 查询各科成绩最高分、最低分和平均分,以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率(及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90)。
    要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列

    在这里插入图片描述

    15: 按平均成绩进行排序,显示总排名和各科排名,Score 重复时保留名次空缺

    16: 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺

    17:统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比
    count() !!! 因为人数,个数 不能用sum()

    在这里插入图片描述18:查询各科成绩前三名的记录

    19: 查询出只选修两门课程的学生学号和姓名

    在这里插入图片描述
    20:查询每门课程被选修的学生数

    在这里插入图片描述

    21.查询男生、女生人数

    在这里插入图片描述

    22:查询名字中含有「风」字的学生信息

    在这里插入图片描述
    23:找到同名的名字并统计个数

    在这里插入图片描述

    23.1嵌套查询列出同名的全部学生的信息

    在这里插入图片描述

    24: 查询 1990 年出生的学生名单

    在这里插入图片描述
    25:查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列

    在这里插入图片描述

    26:查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩

    在这里插入图片描述

    27:查询课程名称为「数学」,且分数低于 60 的学生姓名和分数

    在这里插入图片描述

    28:查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)

    在这里插入图片描述

    29:查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数

    在这里插入图片描述

    30:查询不及格的课程

    (方法一)
    在这里插入图片描述
    (方法二)
    在这里插入图片描述

    31:查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名

    在这里插入图片描述

    32:求每门课程的学生人数

    在这里插入图片描述

    1. 成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

    在这里插入图片描述

    在这里插入图片描述

    34:成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

    35:查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

    在这里插入图片描述

    36:查询每门功成绩最好的前两名

    37:统计每门课程的学生选修人数(超过 5 人的课程才统计)。

    在这里插入图片描述

    38:检索至少选修两门课程的学生学号

    在这里插入图片描述

    39:查询选修了全部课程的学生信息

    在这里插入图片描述

    40:查询各学生的年龄,只按年份来算

    在这里插入图片描述
    41:按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一

    在这里插入图片描述
    42. 查询本周过生日的学生
    在这里插入图片描述
    43. 查询下周过生日的学生

    在这里插入图片描述

    1. 查询本月过生日的学生

    在这里插入图片描述
    45:查询下月过生日的学生
    在这里插入图片描述

    三:经典题 附加题

    1:查询出每门课都大于80 分的学生姓名

    在这里插入图片描述
    2:删除除了自动编号不同, 其他都相同的学生冗余信息

    1 2005001 张三 0001 数学 69
    2 2005001 张三 0001 数学 69
    在这里插入图片描述
    3. 一个叫 team 的表,里面只有一个字段name, 一共有4 条纪录,分别是a,b,c,d, 对应四个球对,现在四个球对进行比赛,用一条sql 语句显示所有可能的比赛组合

    在这里插入图片描述
    4:

    在这里插入图片描述

    在这里插入图片描述
    5:从数据表中查询出所有月份的发生额都比1991 年相应月份的发生额高的科目。
    (select )b 作为 第二个表

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    6:pid分组,调整数据格式

    在这里插入图片描述

    在这里插入图片描述


    四:知识补充
    1:order by
    ①:order by子句 可使用列别名
    因为:执行顺序
    在这里插入图片描述
    ②:表表达式包括视图,内联表值函数,子查询 不能用 order by。

    2:

    展开全文
  • 50SQL练习及答案与详细分析 数据表介绍 –1.学生表 Student(SId,Sname,Sage,Ssex) –SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 –2.课程表 Course(CId,Cname,TId) –CId 课程编号,Cname 课程...
  • 50SQL练习及答案与详细分析(题目和数据初始化) 50SQL练习及答案与详细分析(01~05) 50SQL练习及答案与详细分析(06~10) 1.查询”01″课程比”02″课程成绩高的学生的信息及课程分数. SELECT ...
  • SQL经典50题练习

    千次阅读 2021-09-26 09:17:23
    SQL这套50题在网上流传很广,是比较经典、全面的一套题,最近刚入职数据开发工程师,SQL需要加强,因此自然不能错过这套题,答案都是自己写的,有错误或者可以改进的地方欢迎指出。 数据表介绍 题中所需数据来自...

    SQL这套50题在网上流传很广,是比较经典、全面的一套题,最近刚入职数据开发工程师,SQL需要加强,因此自然不能错过这套题,每一道题都是自己写的,不会的题有看过其他大佬的解析,然后自己再写一次,可能有些题答案会一样,有错误或者可以改进的地方欢迎指出。

    题目来自:50道SQL练习题及答案与详细分析 - 简书

    不会的题一般用搜索看经验找灵感,没有详细记录,主要借鉴这位大佬的视频,讲得非常详细。【数据分析】- SQL面试50题 - 跟我一起打怪升级 一起成为数据科学家_哔哩哔哩_bilibili

    数据表介绍

    题中所需数据来自四个表,分别是学生-成绩-课程-老师,此处列出四个表的字段与关联图

    创建表及插入数据

    学生表Student

    create table Student(SId varchar(10),Sname varchar(10),Sage datetime,Ssex varchar(10));
    insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
    insert into Student values('02' , '钱电' , '1990-12-21' , '男');
    insert into Student values('03' , '孙风' , '1990-12-20' , '男');
    insert into Student values('04' , '李云' , '1990-12-06' , '男');
    insert into Student values('05' , '周梅' , '1991-12-01' , '女');
    insert into Student values('06' , '吴兰' , '1992-01-01' , '女');
    insert into Student values('07' , '郑竹' , '1989-01-01' , '女');
    insert into Student values('09' , '张三' , '2017-12-20' , '女');
    insert into Student values('10' , '李四' , '2017-12-25' , '女');
    insert into Student values('11' , '李四' , '2012-06-06' , '女');
    insert into Student values('12' , '赵六' , '2013-06-13' , '女');
    insert into Student values('13' , '孙七' , '2014-06-01' , '女');

    课程表 Course

    create table Course(CId varchar(10),Cname nvarchar(10),TId varchar(10));
    insert into Course values('01' , '语文' , '02');
    insert into Course values('02' , '数学' , '01');
    insert into Course values('03' , '英语' , '03');

    教师表 Teacher

    create table Teacher(TId varchar(10),Tname varchar(10));
    insert into Teacher values('01' , '张三');
    insert into Teacher values('02' , '李四');
    insert into Teacher values('03' , '王五');

    成绩表 SC

    create table SC(SId varchar(10),CId varchar(10),score decimal(18,1));
    insert into SC values('01' , '01' , 80);
    insert into SC values('01' , '02' , 90);
    insert into SC values('01' , '03' , 99);
    insert into SC values('02' , '01' , 70);
    insert into SC values('02' , '02' , 60);
    insert into SC values('02' , '03' , 80);
    insert into SC values('03' , '01' , 80);
    insert into SC values('03' , '02' , 80);
    insert into SC values('03' , '03' , 80);
    insert into SC values('04' , '01' , 50);
    insert into SC values('04' , '02' , 30);
    insert into SC values('04' , '03' , 20);
    insert into SC values('05' , '01' , 76);
    insert into SC values('05' , '02' , 87);
    insert into SC values('06' , '01' , 31);
    insert into SC values('06' , '03' , 34);
    insert into SC values('07' , '02' , 89);
    insert into SC values('07' , '03' , 98);

    练习题目

    1. 查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数

    1.1 查询同时存在" 01 "课程和" 02 "课程的情况

    1.2 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )

    1.3 查询不存在" 01 "课程但存在" 02 "课程的情况

    2. 查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩

    3. 查询在 SC 表存在成绩的学生信息

    4. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )

    4.1 查有成绩的学生信息

    5. 查询「李」姓老师的数量

    6. 查询学过「张三」老师授课的同学的信息

    7. 查询没有学全所有课程的同学的信息

    8. 查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息

    9. 查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息

    10. 查询没学过"张三"老师讲授的任一门课程的学生姓名

    11. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩

    12. 检索" 01 "课程分数小于 60,按分数降序排列的学生信息

    13. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

    14. 查询各科成绩最高分、最低分和平均分:

    以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率

    及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90

    要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列

    15. 按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺

    15.1 按各科成绩进行排序,并显示排名, Score 重复时合并名次

    16. 查询学生的总成绩,并进行排名,总分重复时保留名次空缺

    16.1 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺

    17. 统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比

    18. 查询各科成绩前三名的记录

    19. 查询每门课程被选修的学生数

    20. 查询出只选修两门课程的学生学号和姓名

    21. 查询男生、女生人数

    22. 查询名字中含有「风」字的学生信息

    23. 查询同名同性学生名单,并统计同名人数

    24. 查询 1990 年出生的学生名单

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

    26. 查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩

    27. 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数

    28. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)

    29. 查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数

    30. 查询不及格的课程

    31. 查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名

    32. 求每门课程的学生人数

    33. 成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

    34. 成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成       绩

    35. 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

    36. 查询每门功成绩最好的前两名

    37. 统计每门课程的学生选修人数(超过 5 人的课程才统计)。

    38. 检索至少选修两门课程的学生学号

    39. 查询选修了全部课程的学生信息

    40. 查询各学生的年龄,只按年份来算

    41. 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一

    42. 查询本周过生日的学生

    43. 查询下周过生日的学生

    44. 查询本月过生日的学生

    45. 查询下月过生日的学生

    解答

    1. 查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数

    先把01课程和02课程的成绩分别select出两个表,再把两个表连接在一起,用where写大于

    select t1.SId, t1.CId, t1.score, t2.CId as CId_2, t2.score as score_2
    from (select * 
    			from SC 
    			where CId = '01') as t1
    			inner join (select * 
    								 from SC 
    								 where CId = '02') as t2
    								 on t1.SId = t2.SId
    where t1.score > t2.score

    1.1 查询同时存在" 01 "课程和" 02 "课程的情况

    只要同时选了01、02课程,输出这个学生选的所有课的相关信息

    由于子查询返回的结果多于一行,不加any会报错

    select student.SId, Sname, CId, score
    from student left join SC 
    on student.SId = SC.SId
    where student.SId = any(select SC.SId
    						from SC
    						where CId in ('01', '02'))

    1.2 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )

    select * from (select * 
    			   from SC
    			   where SC.CId='01')as t1 
    			   left join (select * 
    						  from SC 
    						  where SC.CId='02')as t2 
    						  on t1.SId=t2.SId

    1.3 查询不存在" 01 "课程但存在" 02 "课程的情况

    查出所有存在02课程的情况,再筛掉有01课程的

    select * 
    from SC
    where CId = '02' and SId not in(select SId
    								from SC
    								where SC.CId = '01')

    2. 查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩

    select student.SId, Sname, avg(score)
    from student left join SC
    on student.SId = SC.SId
    group by SId
    having avg(score) >= 60

    3. 查询在 SC 表存在成绩的学生信息

    select distinct student.*
    from student, SC
    where student.SId = SC.SId

    4. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )

    select student.SId, Sname, COUNT(CId), SUM(score)
    from student, SC
    where student.SId = SC.SId
    group by SId
    

    # 需要显示没选课学生时,需要用join

    select t1.SId, Sname, CourseSum, ScoreSum
    from (select student.SId, Sname
    			from student
    			)t1 
    			left join (select SC.SId, COUNT(SC.CId) as CourseSum, 
    						      SUM(SC.score) as ScoreSum
    					   from SC
    					   group by SC.SId)t2
    					   on t1.SId = t2.SId

    4.1 查有成绩的学生信息

    select distinct student.*
    from student, SC
    where student.SId = SC.SId AND SC.score is not NULL
    

    5. 查询「李」姓老师的数量

    通配符要和like搭配,我总写成=

    select *
    from teacher
    where Tname like '李%'

    6. 查询学过「张三」老师授课的同学的信息

    select student.*
    from student 
    left join SC
    on student.SId = SC.SId
    where CId = (select TId
    			 from teacher
    			 where Tname = '张三')

    7. 查询没有学全所有课程的同学的信息

    计算所有课程的数量和每个学生选课数量,筛选掉课程数量不相等的学生id。

    select *
    from student 
    where student.SId not in (select sc.SId
    						  from sc
    						  group by sc.SId
    						  having count(sc.CId)= (select count(CId) from course))

    8. 查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息

    查询出01学号同学选的课,用in在所有学生的选课里查询符合条件的

    select distinct student.*
    from student left join sc on student.SId = sc.SId
    where CId in (select CId
    			  from sc
    			  where SId = '01') and student.SId != '01'

    9. 查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息

    两层查询保证筛选出来的学生(选的课程都是01学生选过的+所选课程数量一样)

    不会出现所选课程包含01学生课程但又选了其他额外课程,或者只选了01学生的一部分课程这些情况,可保证所选课程完全一样。

    select * from Student 
    where sid in (select SId from SC # 查询所选课程数量和01学生一样的学生
    							where SId != '01' 
    							group by SId 
    							having count(CId) = (select count(CId) 
    												 from SC where SId = '01')
    						    # 去掉所选课程中选了01学生未选课程的人																 
    							and SId not in (select distinct SId 
    											from sc
    											where CId not in (select CId from sc
    										    where SId = '01'))
    )

    10. 查询没学过"张三"老师讲授的任一门课程的学生姓名* 

    连接三个表,找出那些学生选了张三老师的课,再排除掉,

    select student.Sname
    from student 
    where SId not in (select s.SId
    				  from student s left join sc on s.SId = sc.SId
    								 left join teacher t on sc.CId = t.TId
    								 where Tname = '张三')

    11. 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩

    select student.SId, Sname, avg(score)
    from student left join sc on student.SId = sc.SId
    where score < 60
    group by SId
    having count(*) > 1

    12. 检索" 01 "课程分数小于 60,按分数降序排列的学生信息

    select s.*
    from student s left join sc on s.SId = sc.SId
    where CId = '01' and score < 60
    order by score DESC

    13. 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

    直接select会只显示每个学生的一条课程记录,所以再和sc表join一下

    select *
    from sc left join(select SId, avg(sc.score) as AvgScore
    					from sc
    					group by SId) t
    		on sc.SId = t.SId
    order by AvgScore DESC

    14. 查询各科成绩最高分、最低分和平1均分

    以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率

    及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90

    要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列

    select sc.CId ,max(sc.score)as 最高分, min(sc.score)as 最低分, 
    				AVG(sc.score)as 平均分, count(*)as 选修人数,
    				sum(case when sc.score>=60 then 1 else 0 end )/count(*)as 及格率,
    				sum(case when sc.score>=70 and sc.score<80 then 1 else 0 end )/count(*)as 中等率,
    				sum(case when sc.score>=80 and sc.score<90 then 1 else 0 end )/count(*)as 优良率,
    				sum(case when sc.score>=90 then 1 else 0 end )/count(*)as 优秀率 
    from sc
    GROUP BY sc.CId
    ORDER BY count(*)DESC, sc.CId ASC

    15. 按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺

    15.1 按各科成绩进行排序,并显示排名, Score 重复时合并名次

    16. 查询学生的总成绩,并进行排名,总分重复时保留名次空缺

    16.1 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺

    暂时没想出太好的解法,在网上看了一圈也感觉没有很满意的答案,最近工作有点忙,想到了再补上。

    17. 统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比

    select c.CId, c.Cname, sum(case when sc.score <= 100 and sc.score > 85 then 1 else 0 end) as '[100-85]',
    						sum(case when sc.score <= 85 and sc.score > 70 then 1 else 0 end) as '[85-70]',
    						sum(case when sc.score <= 70 and sc.score > 60 then 1 else 0 end) as '[70-60]',
    						sum(case when sc.score <= 60 and sc.score > 0 then 1 else 0 end) as '[60-0]'
    from sc left join course c on sc.CId = c.CId
    group by c.CId

    18. 查询各科成绩前三名的记录

    看到这道题想起之前看过的一篇窗口函数解析,其中的例子非常相似,即分组后组内排序。

    通俗易懂的学会:SQL窗口函数 - 知乎

    <窗口函数> over (partition by <用于分组的列名>
                    order by <用于排序的列名>)

    第一层select建立单独的rk列,代表课程内排名

    第二层select查询所有相关信息(SId,CId,score,rk)

    select *
    from(select *,
    	 rank() over (partition by CId
    				  order by score) as rk
    from sc) r
    where rk <= 3

    19. 查询每门课程被选修的学生数

    select CId, count(SId) as SIdnum
    from SC
    group by CId
    

    20. 查询出只选修两门课程的学生学号和姓名

    select student.SId, Sname, count(CId) as CIdnum
    from student left join sc on student.SId = sc.SId
    group by student.SId
    having CIdnum = 2

    21. 查询男生、女生人数

    select Ssex, count(*)
    from student
    group by Ssex

    22. 查询名字中含有「风」字的学生信息

    select *
    from student
    where Sname like '%风%'

    23. 查询同名同性学生名单,并统计同名人数

    select Sname, count(SId) as num
    from student
    group by Sname
    having num > 1

    24. 查询 1990 年出生的学生名单

    select *
    from student
    where year(Sage) = 1990

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

    多种标准排序时,直接用逗号连接,优先的写前面。

    select CID, avg(score) as AvgScore
    from sc
    group by CId
    order by AvgScore DESC, CId ASC

    26. 查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩

    select s.SId, s.Sname, avg(score) as AvgScore 
    from student s left join sc on s.SId = sc.SId
    group by s.SId
    having AvgScore >= 85

    27. 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数

    select s.Sname, score
    from student s left join sc on s.SId = sc.SId
    			   left join course on sc.CId = course.CId
    where Cname = '数学' and score < 60

    28. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)

    select *
    from student s left join sc on s.SId = sc.SId
    				left join course on sc.CId = course.CId

    29. 查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数

    select Sname, Cname, score
    from student s left join sc on s.SId = sc.SId
    				left join course on sc.CId = course.CId
    where score > 70

    30. 查询不及格的课程

    select *
    from sc
    where score < 60

    31. 查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名

    原数据里没有满足条件的学生,所以查出来是空的也正常,但有两个等于80的。

    select s.SId, Sname, score
    from student s left join sc on s.SId = sc.SId
    where CId = '01' and score > 80

    32. 求每门课程的学生人数

    select CId, count(SId) as StudentNum
    from sc
    group by CId
    

    33. 成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

    如果有两个一样的最高分,用limit1也可以保证只有一个人。

    select s.*
    from student s left join sc on s.SId = sc.SId
    				left join course c on sc.CId = c.CId
    				left join teacher t on c.TId = t.TId
    where Tname = '张三'
    order by score DESC
    limit 1

    34. 成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成       绩

    从张三老师教的课里计算最高分,然后在选了这门课的人里挑出拥有这个最高分的学生。

    三段left join重复了一次,想了半天没有想出解决方法,在网上看了一些其他人写的也差不多都是这样,暂时这样写着吧。

    select s.*
    from student s left join sc on s.SId = sc.SId
    								left join course c on sc.CId = c.CId
    								left join teacher t on c.TId = t.TId
    where Tname = '张三' and score in (select max(score) 
    									from student s left join sc on s.SId = sc.SId
    													left join course c on sc.CId = c.CId																									 
                                                        left join teacher t on c.TId = t.TId
    									where Tname = '张三' ) 

    35. 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

    把一个表重命名创建出新的表,可以直接用来比较。

    select distinct a.* 
    from sc a 
    left join sc b on a.CId != b.CId
    where a.score = b.score

    36. 查询每门功课成绩最好的前两名

    创建出一个一样的表sc1,"count(*)"计算次数出满足“同课程内某个分数比其他分数小的次数”

    <2代表只有一次或零次,即第二名或第一名,即可满足题目条件。

    where条件中写的是sc1表里满足上述条件的score(sc1.score < sc.score),因为在from中已经把查询范围限定在sc1里了,如果select sc.*,则会报错。

    select *
    from sc sc1
    where (select count(*) 
    		from sc
    		where sc1.CId = sc.CId and sc1.score < sc.score
    )<2 
    order by CId, score DESC

    37. 统计每门课程的学生选修人数(超过 5 人的课程才统计)

    select CId, count(SId) as num
    from sc
    group by CId
    having num > 5

    38. 检索至少选修两门课程的学生学号

    select SId
    from student 
    where SId in (select SId
    				from sc
    				group by SId
    				having count(*) > 1)

    39. 查询选修了全部课程的学生信息

    学号分组后计算每个学号有几行(选了几门课),与总课程数是否相等

    select *
    from student 
    where SId in (select SId
    				from sc
    				group by SId
    				having count(*) = (select count(*)
    									from course))
    			

    40. 查询各学生的年龄,只按年份来算

    select *, year(now())-year(sage) as 年龄
    from Student

    41. 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一

    select Sname, floor(datediff(CURRENT_DATE, Sage)/365) as age
    from student

    42. 查询本周过生日的学生

    select *, week(Sage), week(now()) 
    from Student 
    where week(Sage) = week(now());

    43. 查询下周过生日的学生

    在42题基础上+1

    select *, week(Sage), week(now()) 
    from Student 
    where week(Sage) = week(now()) + 1;

    44. 查询本月过生日的学生

    select *, month(Sage), month(now()) 
    from Student 
    where month(Sage) = month(now());

    45. 查询下月过生日的学生

    select *, month(Sage), month(now()) 
    from Student 
    where month(Sage) = month(now()) + 1;

    展开全文
  • 经典SQL语句50题

    2010-12-02 12:12:13
    一个项目涉及到50SQL语句。(经典)
  • SQL 经典50题(题目+解答)(1)

    千次阅读 2022-03-07 16:12:20
    SQL 经典50题(题目+解答)(1)

    0. 后续(2)-(3)

    题虽是老题,但表格和题目都是自己最近实践过的,同时使用Navicat For MySQL也实现了线下刷题,能更加直观地观察数据。题不多,但刷完对理解SQL的基础概念的理解和常用技巧的练习都有不少帮助。

    若有帮助欢迎点赞、收藏、评论~

    1. 表格

    题目涉及到四张表格:
    (后面有实现代码)

    • 学生表(Student)
      在这里插入图片描述

    • 课程表(Course)

      在这里插入图片描述

    • 教师表(Teacher)
      在这里插入图片描述

    • 成绩表(Score)
      在这里插入图片描述

    附表格创建代码:

    # Student 学生表
    CREATE TABLE Student
    (
    s_id VARCHAR(20),
    s_name VARCHAR(20) NOT NULL,
    s_birth VARCHAR(20) NOT NULL, 
    s_sex VARCHAR(10) NOT NULL,
    PRIMARY KEY(s_id)
    );
    
    INSERT INTO Student VALUES('01', '赵雷', '1990-01-01', '男');
    INSERT INTO Student VALUES('02', '钱电', '1990-12-21', '男');
    INSERT INTO Student VALUES('03', '孙风', '1990-05-20', '男');
    INSERT INTO Student VALUES('04', '李云', '1990-08-06', '男');
    INSERT INTO Student VALUES('05', '周梅', '1991-12-01', '女');
    INSERT INTO Student VALUES('06', '吴兰', '1992-03-01', '女');
    INSERT INTO Student VALUES('07', '郑竹', '1989-07-01', '女');
    INSERT INTO Student VALUES('08', '王菊', '1990-01-20', '女');
    
    
    # Course 课程表
    CREATE TABLE Course
    (
    c_id VARCHAR(20),
    c_name VARCHAR(20) NOT NULL,
    t_id VARCHAR(20) NOT NULL,
    PRIMARY KEY(c_id)
    );
    
    INSERT INTO Course VALUES('01', '语文', '02');
    INSERT INTO Course VALUES('02', '数学', '01');
    INSERT INTO Course VALUES('03', '英语', '03');
    
    
    # Teacher 教师表
    CREATE TABLE Teacher
    (
    t_id VARCHAR(20),
    t_name VARCHAR(20) NOT NULL DEFAULT '',
    PRIMARY KEY(t_id)
    );
    
    INSERT INTO Teacher VALUES('01', '张三');
    INSERT INTO Teacher VALUES('02', '李四');
    INSERT INTO Teacher VALUES('03', '王五');
    
    
    # Score 分数表
    CREATE TABLE Score
    (
    s_id VARCHAR(20),
    c_id VARCHAR(20),
    s_score INT(3),
    PRIMARY KEY(s_id, c_id)  # 注意这里是联合主键
    );
    
    INSERT INTO Score VALUES('01', '01', 80);
    INSERT INTO Score VALUES('01', '02', 90);
    INSERT INTO Score VALUES('01', '03', 99);
    INSERT INTO Score VALUES('02', '01', 70);
    INSERT INTO Score VALUES('02', '02', 60);
    INSERT INTO Score VALUES('02', '03', 80);
    INSERT INTO Score VALUES('03', '01', 80);
    INSERT INTO Score VALUES('03', '02', 80);
    INSERT INTO Score VALUES('03', '03', 80);
    INSERT INTO Score VALUES('04', '01', 50);
    INSERT INTO Score VALUES('04', '02', 30);
    INSERT INTO Score VALUES('04', '03', 20);
    INSERT INTO Score VALUES('05', '01', 76);
    INSERT INTO Score VALUES('05', '02', 87);
    INSERT INTO Score VALUES('06', '01', 31);
    INSERT INTO Score VALUES('06', '03', 34);
    INSERT INTO Score VALUES('07', '02', 89);
    INSERT INTO Score VALUES('07', '03', 98);
    
    # 四张表
    SELECT * FROM Student;
    SELECT * FROM Course;
    SELECT * FROM Teacher;
    SELECT * FROM Score;
    
    

    2. 题目

    (看下面)

    3. 题目 + 解答

    1、查询课程编号为“01”的课程比“02”的课程成绩高的所有学生的学号和成绩

    多次将Score表自连接实现将同一个字段两次使用:

    ## 自连接
    SELECT st.*, m.s_score1, m.s_score2
    FROM 
    		(
    		SELECT sc1.s_id, sc1.s_score s_score1, sc2.s_score s_score2  # 注意有两个成绩
    		FROM Score sc1
    		JOIN Score sc2 
    		ON sc1.s_id = sc2.s_id 
    			 AND sc1.c_id = '01'  #  因为是INNER JOIN 下面的条件可以不写在WHERE中
    			 AND sc2.c_id = '02'
    			 AND sc1.s_score > sc2.s_score
    		) m
    JOIN Student st 
    ON m.s_id = st.s_id;
    

    2、查询平均成绩大于60分的学生的学号和平均成绩

    SELECT s_id, AVG(s_score) avg_score 
    FROM Score
    GROUP BY s_id
    HAVING avg_score > 60;
    

    2.1、所有成绩小于60分的学生信息

    SELECT st.s_id, st.s_name, st.s_birth, st.s_sex
    FROM Student st
    JOIN (
    		SELECT s_id, MAX(s_score) min_score  # 可以对上边界来进行限制,来满足【所有】这个条件
    		FROM Score
    		GROUP BY s_id
    		HAVING min_score < 60) t 
    ON st.s_id = t.s_id
    ## 也可以使用 WHERE > 60 + NOT IN 的思路
    

    2.2、查询平均成绩小于60分的学生的学号和平均成绩,考虑没参加考试的情况

    -- ## 错误:当前使用计数的方式来设置条件,无法匹配到没参加考试的情况 (考点其实应该是 LEFT JOIN)
    -- SELECT  s_id,
    -- 				CASE
    -- 			      WHEN COUNT(s_id) = 1 THEN SUM(s_score) / 3  #注意s_score必须在聚合函数内
    -- 						WHEN COUNT(s_id) = 2 THEN SUM(s_score) / 3
    -- 						WHEN COUNT(s_id) = 3 THEN AVG(s_score)
    -- 						ELSE 0
    -- 			  END avg_score
    -- FROM Score
    -- GROUP BY s_id
    -- HAVING avg_score < 60
    
    # 正解 (还有更简单的方法:IFNULL(col, value))
    SELECT m.s_id, 
           AVG(m.score) avg_score
    FROM 
    		(
    		SELECT st.s_id, 
    					 IF(sc.s_score IS NULL, 0, sc.s_score) score
    		FROM Student st 
    		LEFT JOIN Score sc 
    		ON st.s_id = sc.s_id 
    		) m  # 将未参加考试的部分记零分
    GROUP BY m.s_id
    HAVING avg_score < 60;
    

    另解:

    # 使用IFNULL() 一步到位
    SELECT m.s_id, AVG(IFNULL(m.s_score, 0)) avg_score
    FROM 
    		(
    		SELECT st.s_id, sc.s_score
    		FROM Student st 
    		LEFT JOIN Score sc 
    		ON st.s_id = sc.s_id
    		) m 
    GROUP BY m.s_id
    HAVING AVG(IFNULL(m.s_score, 0)) < 60  
    -- HAVING avg_score < 60  # why this also OK !!(记住HAVING 可以使用SELECT 字段的别名(突破执行顺序的羁绊!))
    
    

    3、查询所有学生的学号、姓名、选课数、总成绩

    -- ## 错误:没有考虑到可能有学生完全没有选课,应该使用LEFT JOIN
    -- SELECT st.s_id, st.s_name, COUNT(sc.c_id), SUM(sc.s_score)
    -- FROM Student st 
    -- JOIN Score sc 
    -- ON st.s_id = sc.s_id
    -- GROUP BY st.s_id, st.s_name
    
    ## 正解
    SELECT st.s_id, st.s_name, COUNT(sc.c_id), SUM(sc.s_score)
    FROM Student st 
    LEFT JOIN Score sc 
    ON st.s_id = sc.s_id
    GROUP BY st.s_id, st.s_name
    
    

    4、查询姓“猴”的老师的个数

    SELECT COUNT(t_name)
    FROM Teacher
    WHERE t_name LIKE "猴%"
    

    5、查询没学过“张三”老师课的学生的学号、姓名

    -- ## 错误(没选课程和选了课程的同学都没找出来)
    -- SELECT DISTINCT st.s_id, st.s_name   # 注意 DISTINCT 去重
    -- FROM Student st
    -- JOIN Score sc 
    -- ON st.s_id = sc.s_id 
    -- JOIN Course c
    -- ON sc.c_id = c.c_id
    -- JOIN Teacher t 
    -- ON c.t_id = t.t_id
    -- WHERE t.t_name != "张三"
    
    ## 正解:【没有】这个条件可以使用 NOT IN
    SELECT st.s_id, st.s_name
    FROM  Student st 
    WHERE s_id NOT IN 
    			(
    			SELECT sc.s_id 
    			FROM Score sc
    			JOIN Course c 
    			ON sc.c_id = c.c_id 
    			JOIN Teacher t
    			ON c.t_id = t.t_id
    			WHERE t.t_name = "张三"
    			)
    

    6、查询学过“张三”老师所教的所有课的同学的学号、姓名

    (后来觉得这里用count的方法会更好)

    ## 有点难度,想不过来就很难【自连接的情况】
    SELECT st.s_id, st.s_name
    FROM Student st 
    WHERE st.s_id IN 
    			(
    			SELECT DISTINCT sc.s_id
    			FROM
    					(SELECT c.c_id
    					FROM Course c
    					JOIN Teacher t 
    					ON c.t_id = t.t_id
    					WHERE t.t_name = "张三") s  # “张三”老师所教的所有课
    			LEFT JOIN Score sc
    			ON s.c_id = sc.c_id
    			WHERE sc.s_id IS NOT NULL    
    			);
    

    7、查询学过编号为“01”的课程并且也学过编号为“02”的课程的学生的学号、姓名(!)

    -- ## 不严谨的奇葩解法
    -- SELECT st.s_id, st.s_name
    -- FROM (
    -- 			SELECT s_id, Group_CONCAT(c_id) c_str
    -- 			FROM Score 
    -- 			GROUP BY s_id) t  # 分组进行进行行合并
    -- JOIN Student st 
    -- ON t.s_id = st.s_id
    -- WHERE c_str LIKE '%01%' AND c_str LIKE '%02%'
    -- 
    
    # 正解:自连接
    SELECT st.s_id, st.s_name
    FROM Student st 
    JOIN 
    		(
    		SELECT sc1.* 
    		FROM Score sc1 
    		JOIN Score sc2 
    		ON sc1.s_id = sc2.s_id
    		WHERE sc1.c_id = '01'     # 这里不需要使用IN,也不需要纠结顺序问题,因为两张表都是Score
    					AND sc2.c_id = '02'
    		) m 
    ON st.s_id = m.s_id;
    

    7.1、查询学过编号为“01”的课程但没有学过编号为“02”的课程的学生的学号、姓名(!)

    ## 同样的奇葩解法
    -- SELECT DISTINCT st.s_id, st.s_name  ## 注意使用DISTINCT
    -- FROM (
    -- 			SELECT s_id, Group_CONCAT(c_id) c_str
    -- 			FROM Score 
    -- 			GROUP BY s_id) t  # 分组进行进行行合并
    -- JOIN Student st 
    -- ON t.s_id = st.s_id
    -- WHERE c_str LIKE '%01%' AND c_str NOT LIKE '%02%'
    
    ## 正解:自连接
    SELECT DISTINCT st.s_id, st.s_name  ## 注意使用DISTINCT
    FROM Student st 
    JOIN 
    		(
    		SELECT sc1.* 
    		FROM Score sc1
    		JOIN Score sc2 
    		ON sc1.c_id = '01'   ## 无关次序
    			 AND sc2.c_id != '02'
    		) m
    ON st.s_id = m.s_id
    

    8、查询课程编号为“02”的总成绩

    SELECT SUM(s_score)
    FROM Score
    GROUP BY c_id
    -- WHERE c_id = '02'  # 考察 HAVING,聚合条件限制不能使用WHERE
    HAVING c_id = '02'
    

    9、查询所有课程成绩小于60分的学生的学号、姓名

    ## 【所有】这个条件使用边界值进行限定
    SELECT DISTINCT st.s_id, st.s_name
    FROM Student st 
    JOIN 
    		(
    		SELECT s_id, 
    					 MIN(s_score) min_score
    		FROM Score s
    		GROUP BY s.s_id
    		HAVING min_score < 60
    		) s # 满足条件的学生
    ON st.s_id = s.s_id
    

    10、查询没有学全所有课的学生的学号、姓名 (!)

    ## 这题用LEFT JOIN也不好使
    SELECT DISTINCT st.s_id, st.s_name
    FROM Student st 
    JOIN 
    		(
    		SELECT m.s_id
    		FROM (
    					SELECT s_id, COUNT(c_id) cnt 
    					FROM Score
    					GROUP BY s_id
    				 ) m
    		WHERE m.cnt != (SELECT COUNT(c_id) FROM Course)
    		) n  # 子查询注意都要使用别名
    ON st.s_id = n.s_id
    

    11、查询至少有一门课与学号为“01”的学生所学课程相同的学生的学号和姓名

    -- ## 错误:误解题意+没有排除自己
    -- SELECT st.s_id, st.s_name
    -- FROM 
    -- 		(
    -- 		SELECT DISTINCT s_id
    -- 		FROM  Score
    -- 		WHERE c_id = '01'
    -- 		) m  # 至少有一门课与学号为“01”的学生id
    -- JOIN Student st 
    -- WHERE m.s_id = st.s_id
    
    
    SELECT DISTINCT st.s_id, st.s_name 
    FROM Student st
    JOIN Score sc
    ON st.s_id = sc.s_id 
    WHERE sc.c_id IN
    			(SELECT c_id FROM Score WHERE s_id = '01') 
    			AND sc.s_id != '01'  # 将自己排除
    
    展开全文
  • Spark_Sql50题(DataFrame)

    万次阅读 2021-12-14 00:29:58
    表名和字段信息 课程表: Course c_id:课程编号 c_name:课程名称 t_id:教师编号 学生表: Student s_id:学号 s_name:姓名 ...CREATE DATABASE sql50; use sql50; DROP TABLE IF EXISTS `Course`; C
  • SQL面试经典50题

    2022-04-30 09:27:04
    经典SQL面试50题 数据库面试题
  • 练习总结sql面试50题(2021-12-27完结)

    千次阅读 2021-12-21 21:05:57
    SQL面试必会50题(含答案和学习链接)_欢迎来到小丁的技术空间-CSDN博客_sql面试50题 创建数据库 字符集utf8--UTF-8 Unicode 排序规则utf8_unicode_ci 查询选了课程的学生人数 select count(distinct 学号...
  • 在网上盛传着一份非常经典的SQL练习50题,有很多网友进行了练习,SQL脚本也是层出不穷。笔者前段时间也抽空进行了练习,SQL能力也得到了很大的提升。 接下来会分次分享自己的解题方法和思路,希望对读者有所帮助,更...
  • sql50 50道经典SQL练习,练手和复习都很不错 关于 这个项目主要来源是之前在网上流传的50道SQL练习,大小问加起来50道左右,在不断流传的过程中也会有差异,我看到的最早来源是 使用项目 原版用的是Sql Server,...
  • sql50题自练习持续更新(参考知乎)

    千次阅读 2020-01-23 21:50:53
    常见的SQL面试题:经典50题 https://zhuanlan.zhihu.com/p/38354000 SQL面试必会50题 https://zhuanlan.zhihu.com/p/43289968 【数据分析】- SQL面试50题 - 跟我一起打怪升级 一起成为数据科学家 ...
  • sql语句练习50题(Mysql版)

    万次阅读 多人点赞 2017-12-19 00:11:31
    习题来源于网络,sql语句是自己写的。欢迎指正。 表名和字段 –1.学生表 Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别 –2.课程表 Course(c_id,c_name,t_id) – –课程编号, ...
  • hive学习之经典sql50题 hive版(一)

    千次阅读 2018-06-20 17:23:02
    尽管hql与sql差不多,但还是想把学生教师成绩sql版的改个hive版的,一方面提升自己hql能力,一方面希望帮到广大准备入手hive的同学建表:create table student(sid string,sname string,sage int,ssex string) row ...
  • 50SQL练习

    2018-03-01 12:02:02
    50SQL练习,还附带有详细答案,练完后大概就能掌握SQL基本查询语句了
  • SQL经典50题 | 附答案

    万次阅读 多人点赞 2020-05-25 15:51:29
    看完了SQL基础教程,然后再看SQL进阶教程感觉有些不是很懂,于是就开始刷题熟悉⼀下基础知 识,找了⽐较经典的很多⼈都刷过的SQL⾯试50题,B站也有挺好的视频解答,看题先⾃⼰做,不会就看视频解答,感觉难题都在前...
  • sql常见50题--附答案解析

    千次阅读 多人点赞 2019-03-19 19:36:49
    insert into Score values('04' , '01' , 50); insert into Score values('04' , '02' , 30); insert into Score values('04' , '03' , 20); insert into Score values('05' , '01' , 76); insert into Score values...
  • 50题sql面试.docx

    2022-06-21 00:16:54
    50题sql面试.docx50题sql面试.docx50题sql面试.docx50题sql面试.docx50题sql面试.docx50题sql面试.docx50题sql面试.docx50题sql面试.docx
  • 文章Hive面试题SQL测试题目所需数据,包含建表语句 测试数据等等...................

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 62,304
精华内容 24,921
关键字:

sql50题

友情链接: kf_demo.zip