原文地址:

https://blog.csdn.net/xiushuiguande/article/details/79476964

实验数据

CREATE DATABASE IF NOT EXISTS SQL50;
USE SQL50;

CREATE TABLE Student(sid VARCHAR(10),sname VARCHAR(10),sage DATETIME,ssex NVARCHAR(10));
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' , '女');

CREATE TABLE Course(cid VARCHAR(10),cname VARCHAR(10),tid VARCHAR(10));
INSERT INTO Course VALUES('01' , '语文' , '02');
INSERT INTO Course VALUES('02' , '数学' , '01');
INSERT INTO Course VALUES('03' , '英语' , '03');

CREATE TABLE Teacher(tid VARCHAR(10),tname VARCHAR(10));
INSERT INTO Teacher VALUES('01' , '张三');
INSERT INTO Teacher VALUES('02' , '李四');
INSERT INTO Teacher VALUES('03' , '王五');

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);

4张表的结构关系

Course课程表:

  课程ID、课程名、教师ID

SC成绩表:

  学生ID、课程ID、成绩

Student学生表:

  学生ID、学生姓名、学生年龄、学生性别、

Teacher老师表:

  教师ID、教师名

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

先查询 01课程的成绩表 & 02课程的成绩表

SELECT * FROM `sc` WHERE `cid` = 1;
SELECT * FROM `sc` WHERE `cid` = 2;

使用连接查询,附加 01表的成绩 > 02表的成绩

SELECT
sc1.`sid`
FROM
(SELECT `sid`,`cid`,`score` FROM `sc` WHERE `cid` = 1) AS sc1,
(SELECT `sid`,`cid`,`score` FROM `sc` WHERE `cid` = 2) AS sc2
where
sc1.`sid` = sc2.`sid`
and
sc1.`score` > sc2.`score`;

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

信息都在成绩表里面,要每个学生的全部成绩的平均成绩,

使用AVG聚合函数,然后对学生ID进行分组GROUP BY

查出上面的结果之后再对平均分进行 > 60的筛选

但是为什么SQL查不出结果???

SELECT
`sid`,AVG(`score`) AS 'avg_sc'
FROM
`sc`
GROUP BY
`sid`
HAVING
'avg_sc' > 60;

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

因为在成绩表里面,可以使用分组+计数+求和,求出成绩表内的学号,选课数和总成绩

然后再和学生表进行一个左连接,学生表作为主表,上面的结果表作为从表,因为还存在学生表没有选课的情况

成绩表的筛选

SELECT
`sid`,COUNT(`cid`) AS '选课数',SUM(`score`) as '总成绩'
FROM
`sc`
GROUP BY
`sid`;

左连接学生表

SELECT
S1.`sid`,S1.`sname`,S2.选课数,S2.总成绩
FROM
`student` AS S1
LEFT JOIN (
SELECT `sid`,COUNT(`cid`) AS '选课数',SUM(`score`) AS '总成绩'
FROM `sc`
   GROUP BY `sid`) AS S2
ON
S1.`sid` = S2.`sid`;

已采用内连接:

SELECT
S1.`sid`,S1.`sname`,S2.选课数,S2.总成绩
FROM
`student` AS S1
INNER JOIN (
SELECT `sid`,COUNT(`cid`) AS '选课数',SUM(`score`) AS '总成绩'
FROM `sc`
   GROUP BY `sid`) AS S2
ON
S1.`sid` = S2.`sid`;

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

只在李老师表内查询,使用计数函数

SELECT COUNT(*)
FROM `teacher`
WHERE `tname` LIKE '李%';

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

先筛选张三老师教授的课程ID,可以看到是01课程

SELECT `tid`
FROM `teacher`
WHERE `tname` = '张三';

通过上面的线索,查找课程表,其对应的课程ID是02

select `cid` -- ,`cname`,`tid`
from `course`
where `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '张三');

在成绩表查询没学02课程太难排查了,所以反过来,我们查学了02的学生ID

-- 我们查询学了该课程的学生ID
SELECT DISTINCT `sid`
FROM `sc`
WHERE `cid` = (SELECT `cid` FROM `course` WHERE `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '张三'))

再用上面这张表连接学生表查询【左连接】

SELECT
S1.`sid`,S1.`sname`
FROM
`student` AS S1
LEFT JOIN (SELECT DISTINCT `sid`
FROM `sc`
WHERE `cid` = (SELECT `cid` FROM `course` WHERE `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '张三')))
AS S2
ON
S1.`sid` = S2.`sid`
WHERE
S1.`sid` NOT IN(S2.`sid`);

6、查询学过“```”并且也学过编号“```”课程的同学的学号、姓名;

select s.sid,sname
from student s
join (select a.sid
from (select sid from sc where cid = "01") a
join (select sid from sc where cid = "02") b
on a.sid = b.sid) temp on temp.sid = s.sid;

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

查询张三老师的教师编号:

SELECT `tid` FROM `Teacher` WHERE `tname` = '张三'

然后根据编号查询所授课程:

SELECT `cid`
FROM `Course`
WHERE `tid` = (SELECT `tid` FROM `Teacher` WHERE `tname` = '张三');

然后得到对应的所学课程的学生编号

SELECT `sid`
FROM `SC`
WHERE `cid` IN(
SELECT `cid`
FROM `Course`
WHERE `tid` = (
SELECT `tid`
FROM `Teacher`
WHERE `tname` = '张三'
)
);

最后再联合学生表:

SELECT `sid`,`sname`
FROM `Student`
WHERE `sid` IN (
select `sid`
from `SC`
where `cid` IN(
SELECT `cid`
FROM `Course`
WHERE `tid` = (
SELECT `tid`
FROM `Teacher`
WHERE `tname` = '张三'
)
)
);

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

select a.sid,s.sname
from (select sid,score from sc where cid = "01") a
join (select sid,score from sc where cid = "02") b on a.sid = b.sid
left join student s on a.sid = s.sid
where a.score < b.score;

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

也就是说只要其中一个课程成绩大于60就不算在内

所以就可以先查询大于60分,再取反就行了

大于60分的学生ID:

SELECT `sid` FROM `SC` WHERE `score` > 60

然后取反得到:

SELECT `sid`,`sname`
FROM `Student`
WHERE `sid` NOT IN(SELECT `sid` FROM `SC` WHERE `score` > 60)

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

首先是需要知道全部课程个数

然后这个查询的意思是,计数学生学习课程的个数,如果小于总课数即没学全

但是需要跟学生表关联,他这里的联动真的难理解。。。

SELECT
`sid`,`sname`
FROM
`Student`
WHERE
(SELECT COUNT(*) FROM `SC` WHERE `Student`.`sid` = `SC`.`sid`) < (SELECT COUNT(*) FROM `Course`)

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

select sid,sname
from student
where sid in ( select DISTINCT sid
from sc
join ((select cid from sc where sid = "01"))temp on temp.cid = sc.cid
where sc.sid <> "01"
)

24、查询学生平均成绩及其名次

SELECT
a.sid,
a.avg_score,
SUM(CASE WHEN a.avg_score<b.avg_score THEN 1 ELSE 0 END)+1 scc
FROM
(SELECT sid,AVG(score) avg_score FROM SC GROUP BY sid) a INNER JOIN
(SELECT sid,AVG(score) avg_score FROM SC GROUP BY sid) b
GROUP BY
a.sid,
a.avg_score
ORDER BY
scc

25、查询各科成绩前三名的记录

SELECT * FROM
(
SELECT s.*,a.cid,count(DISTINCT b.score) + 1 AS 名次
FROM sc a
LEFT JOIN sc b ON b.cid = a.cid and a.score < b.score
LEFT JOIN student s ON s.sid = a.cid
group by a.cid,a.sid
order by a.cid , 名次
) resultTab
where 名次 BETWEEN 1 AND 3

26、查询每门课程被选修的学生数

SELECT
`cid`,COUNT(`sid`) '人数'
FROM
`sc`
GROUP BY
`cid`

27、查询出只选修了一门课程的全部学生的学号和姓名

# 查询选课数只有1的学生编号
SELECT
`sid`,COUNT(`cid`) '选课数'
FROM
`sc`
GROUP BY
`sid`
HAVING
`选课数` = 1
# 然后关联学生表进行查询
SELECT
`student`.`sname`,`ss`.`sid`
FROM
`student`,
(SELECT `sid`,COUNT(`cid`) '选课数'
FROM `sc`
GROUP BY `sid`
HAVING `选课数` = 1) `ss`
WHERE
`student`.`sid` IN (`ss`.`sid`)

28、查询男生、女生人数

SELECT `ssex`,COUNT(1) '人数'
FROM `student`
GROUP BY `ssex`

29、查询名字中含有"风"字的学生信息

SELECT *
FROM `student`
WHERE `sname` LIKE '%风%';

使用正则表达式方式实现:

select *
from student
where sname REGEXP "风";

另外:

regexp "^风"
regexp "风$"

30、查询同名同姓学生名单,并统计同名人数

SELECT
`sname`,COUNT(1) AS '同名人数'
FROM
`student`
GROUP BY
`sname`
HAVING
`同名人数` > 1

30、查询同名同性学生名单,并统计同名男生人数

SELECT
`sname`,`ssex`, COUNT(1) AS num
FROM
Student
GROUP BY
`sname`,`ssex`
HAVING
COUNT(1) > 1 AND `ssex`='男'

31、查询1990年出生的学生名单(注:Student表中Sage列的类型是datetime)

SELECT * FROM `student` WHERE YEAR(`sage`) = 1990 ;

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

# 对课程编号分组,求平均分,然后分数升序排列,对课程编号降序排列
SELECT
`cid`,AVG(`score`)
FROM
`sc`
GROUP BY
`cid`
ORDER BY
`cid` DESC;

37、查询不及格的课程,并按课程号从大到小排列

# 在成绩表中的查询
SELECT * FROM `sc` WHERE `score` < 60 ORDER BY `cid` DESC;
# 关联课程表
SELECT
`sc`.*, `course`.`cname`
FROM
`sc`,`course`
WHERE
`sc`.`cid` = `course`.`cid`
AND `sc`.`score` < 60 ORDER BY `sc`.`cid` DESC

38、查询课程编号为"01"且课程成绩在60分以上的学生的学号和姓名;

# 1、现在成绩表查询课程编号为1的
SELECT * FROM `sc` WHERE `cid` = 01;
# 2、再添加分数要求大于60的
SELECT * FROM `sc` WHERE `cid` = 01 AND `score` > 60;
# 3、最后联合学生表获取名字
SELECT
`sc`.*,`student`.`sname`
FROM
`sc`,`student`
WHERE
`sc`.`sid` = `student`.`sid`
AND `sc`.`cid` = 01
AND `score` > 60

40、查询选修“张三”老师所授课程的学生中,成绩最高的学生姓名及其成绩

# 查询老师编号
SELECT `tid` FROM `teacher` WHERE `tname` = '张三';
# 通过编号查询所授课程编号
SELECT `cid` FROM `course` WHERE `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '张三');
# 查询到成绩表学生编号和成绩
SELECT `sid`,`score`
FROM `sc`
WHERE`cid` = (SELECT `cid` FROM `course` WHERE `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '张三'))
ORDER BY `score` DESC
LIMIT 1
# 关联学生表
SELECT
`student`.`sname`,`ss`.`score`
FROM
`student`,
(SELECT `sid`,`score`
FROM `sc`
WHERE`cid` = (SELECT `cid` FROM `course` WHERE `tid` = (SELECT `tid` FROM `teacher` WHERE `tname` = '张三'))
ORDER BY `score` DESC
LIMIT 1) `ss`
WHERE
`student`.`sid` = `ss`.`sid`

42、查询每门功课成绩最好的前两名学生

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

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

# 查询成绩表,按照课程字段分组,计数整个表的记录
# 要求课程大于5记录的倒序排序,并返回人数记录
SELECT cid,COUNT(1) COUNT
FROM SC GROUP BY cid HAVING COUNT(1)>=5 ORDER BY COUNT DESC,cid ;

44、检索至少选修两门课程的学生学号

# 查询成绩表,并计数课程字段
# 对学号字段分组,之后计数的课程字段大于1的记录返回
SELECT `sid`,COUNT(`cid`) AS C
FROM `sc`
GROUP BY `sid`
HAVING C > 1;

45、查询选修了全部课程的学生信息

# 1 先查询课程表的总课程数量
SELECT COUNT(1) FROM Course
# 2 在成绩表中,查询选课累计等于总课程数的学生ID
SELECT sid ,COUNT(cid) count_c FROM SC
GROUP BY sid
HAVING count_c=(SELECT COUNT(1) FROM Course);
# 3 查询学生表得到信息
SELECT `student`.*
from
`student`,
(SELECT sid ,COUNT(cid) count_c FROM SC
GROUP BY sid
HAVING count_c=(SELECT COUNT(1) FROM Course)) as t
WHERE
`student`.`sid` in (t.`sid`)

46、查询各学生的年龄

# 用当前日期求得年份值,再减去字段日期的年份值即可
SELECT Student.*,YEAR(CURDATE())-YEAR(Student.sage) AS '年龄' FROM Student;

47、查询本周过生日的学生

SELECT * FROM Student WHERE WEEKOFYEAR(NOW())-WEEKOFYEAR(sage)=0;

48、查询下周过生日的学生

# 使用周按年换算函数,然后和月一样,下一周就取-1
SELECT * FROM Student WHERE WEEKOFYEAR(NOW())-WEEKOFYEAR(sage)=-1;

49、查询本月过生日的学生

# 先求出现在的时间的月,再和字段月相减得为0的记录即可
SELECT * FROM Student WHERE MONTH(NOW())-MONTH(sage)=0;

50、查询下月过生日的学生

# 本月值,减去字段月的值,相差一个月
# 因为本月大于字段月相减求得的差一定是大于0的
# 所以要查出下一个月过生日的人应该为负数,例如下一个月就-1,下3个月就-3
SELECT * FROM Student WHERE MONTH(NOW())-MONTH(sage)=-1;

【DataBase】SQL50 Training 50题训练的更多相关文章

  1. 【DataBase】SQL45 Training 45题训练

    视频地址: https://www.bilibili.com/video/BV1pp4y1Q7Yv 创建案例库: ------------创建数据库--------------- create dat ...

  2. AtCoder 杂题训练

    前言: 因为要普及了,今年没一等就可以退役去学文化课了,所以暑假把历年noip普及组都刷了一遍,离noip还有50+天,想弄点强化训练什么的. 想了想,就这些天学文化课之余有空就把AtCoder之前那 ...

  3. 经典SQL语句基础50题

    很全面的sql语句大全.都是很基础性的,今天特意整理了下.大家互相学习.大家有好的都可以分享出来,  分享也是一种快乐. --创建数据库 create database SQL50 --打开SQL50 ...

  4. mysql常用语句及实题训练

    基本语句操作 创建数据库: create database database-name 1 删除数据库: drop database database-name 1 修改数据名: RENAME DAT ...

  5. POJ推荐50题

    此文来自北京邮电大学ACM-ICPC集训队 此50题在本博客均有代码,可以在左侧的搜索框中搜索题号查看代码. 以下是原文: POJ推荐50题1.标记“难”和“稍难”的题目可以看看,思考一下,不做要求, ...

  6. JAVA经典算法50题(转)

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/51097928 JAVA经典算法50题 [程序1]   题目:古典问题:有一对兔子, ...

  7. 剑指offer 面试50题

    面试50题: 题目:第一个只出现一次的字符 题:在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置. 解题思路一:利用Python特 ...

  8. MySQL练习50题

    介绍一个学习SQL的网站:https://sqlbolt.com/ 习题来源于网络,SQL语句是自己的练习答案,部分参考了网络上的答案. 花了一晚上的时间做完,个人认为其中的难点有:分组提取前几名的数 ...

  9. Java经典逻辑编程50题

    Java经典逻辑编程50题 2016-11-03 09:29:28      0个评论    来源:Alias_fa的博客    收藏   我要投稿 [程序1] 題目:古典问题:有一对兔子,从出生后第 ...

  10. sql 经典查询50题 思路(一)

    因为需要提高一下sql的查询能力,当然最快的方式就是做一些实际的题目了.选择了这个sql的50题,这次大概做了前10题左右,把思路放上来,也是一个总结. 具体题目见: https://zhuanlan ...

随机推荐

  1. 找不到 .NETFramework,Version=v5.0 的引用程序集。要解决此问题,请为此框架版本安装开发人员工具包(SDK/目标包)或者重新定向应用程序。

    找不到 .NETFramework,Version=v5.0 的引用程序集.要解决此问题,请为此框架版本安装开发人员工具包(SDK/目标包)或者重新定向应用程序. visual studio 2019 ...

  2. k8s配置文件管理

    1.为什么要用configMap ConfigMap是一种用于存储应用所需配置信息的资源类型,用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件. 通过ConfigMap可以方便的 ...

  3. Scrapy框架(六)--图片数据抓取

    基于文件下载的管道类 在scrapy中我们之前爬取的都是基于字符串类型的数据,那么要是基于图片数据的爬取,那又该如何呢? 其实在scrapy中已经为我们封装好了一个专门基于图片请求和持久化存储的管道类 ...

  4. FinalReference 如何使 GC 过程变得拖拖拉拉

    本文基于 OpenJDK17 进行讨论,垃圾回收器为 ZGC. 提示: 为了方便大家索引,特将在上篇文章 <以 ZGC 为例,谈一谈 JVM 是如何实现 Reference 语义的> 中讨 ...

  5. 聊一聊 Monitor.Wait 和 Pluse 的底层玩法

    一:背景 1. 讲故事 在dump分析的过程中经常会看到很多线程卡在Monitor.Wait方法上,曾经也有不少人问我为什么用 !syncblk 看不到 Monitor.Wait 上的锁信息,刚好昨天 ...

  6. SpringBoot 3.x 结合 Swagger3 (Knife4j )踩坑实录

    SpringBoot 3.x + Swagger3 踩坑实录 我的是springboot 版本是:3.2.2 <parent> <groupId>org.springframe ...

  7. Python str 转 b’二进制串

    用raw_unique_escape来编码无义意的二进制串 bytes(strtext, encoding='raw_unique_escape')

  8. HTTP协议 学习:1-报文分析

    HTTP协议 学习:1-报文分析 背景 上一讲我们介绍了HTTP协议的一些 概念 ,对HTTP协议有了一个基础的认识. 正如之前学习MQTT协议一样,我们需要对HTTP的报文进行分析. HTTP 报文 ...

  9. Http基础协议

    浏览器请求方法 http1.0定义了三种: GET: 向服务器获取资源,比如常见的查询请求 POST: 向服务器提交数据而发送的请求 Head: 和get类似,返回的响应中没有具体的内容,用于获取报头 ...

  10. Solo 开发者周刊 (第3期):如何打造令人惊艳的AI体验

    这里会整合 Solo 社区每周推广内容.产品模块或活动投稿,每周五发布.在这期周刊中,我们将深入探讨开源软件产品的开发旅程,分享来自一线独立开发者的经验和见解.本杂志开源,欢迎投稿. 好文推荐 Plu ...