SQL语句

  • 1. 四个表:course、score、student、teacher
  • 2. SQL的题
    • 2.1 查询姓“猴”的学生名单
    • 2.2 查询课程编号为“2”的总成绩
    • 2.3 查询选了课程的学生人数
    • 2.4 查询各科成绩最高和最低的分, 以如下的形式显示:课程号,最高分,最低分
    • 2.5 查询每门课程被选修的学生数
    • 2.6 查询男生、女生人数
    • 2.7 查询平均成绩大于60分学生的学号和平均成绩
    • 2.8 查询选修大于两门课程的学生学号
    • 2.9 查询同名同性学生名单并统计同名人数
    • 2.10 查询分数少于75的课程以及分数,并按课程号从大到小排列
    • 2.11 查询每门课程的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列
    • 2.12 检索课程编号为“4”且分数小于等于90的学生学号,分数,结果按按分数降序排列
    • 2.13 统计每门课程的学生选修人数(超过2人的课程才统计)
  • 3. 复杂查询
    • 3.1 查询存在不及格课程的同学的学号及其平均成绩
    • 3.2 查询所有课程成绩小于等于80分学生的学号、姓名
    • 3.3 查询没有学全所有课的学生的学号、姓名|
    • 3.4 查询出选修了四门课程的全部学生的学号和姓名
    • 3.5 2000年前出生的学生名单
  • 4. topN问题
    • 4.0 按课程号分组取成绩最大值所在行的数据
    • 4.1 按课程号分组取成绩最小值所在行的数据
    • 4.2 查询各科成绩前两名的记录
  • 5. 多表查询
    • 5.1 查询所有学生的学号、姓名、选课数、总成绩
    • 5.2 查询平均成绩大于70的所有学生的学号、姓名和平均成绩
    • 5.3 查询学生的选课情况:学号,姓名,课程号,课程名称
    • 5.4 查询出每门课程的及格人数和不及格人数
    • 5.5 使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计:各分数段人数,课程号和课程名称
    • 5.6 查询课程编号为0003且课程成绩在80分以上的学生的学号和姓名
    • 5.7. 行列如何互换

student表的数据如下:

1. 四个表:course、score、student、teacher

1)向学生表里添加数据

添加数据的sql

insert into student(student_id,name,date,sex)
values('5' , '猴子' , '1989-01-01' , '男');insert into student(student_id,name,date,sex)
values('6' , '小猫' , '1990-12-21' , '女');insert into student(student_id,name,date,sex)
values('7' , '小小马' , '1991-12-21' , '男');insert into student(student_id,name,date,sex)
values('8' , '王思' , '1990-05-20' , '男');

2)成绩表(score)

添加数据的sql

insert into score(course_id,student_id,score)
values('4' , '1' , 80);insert into score(course_id,student_id,score)
values('4' , '2' , 90);insert into score(course_id,student_id,score)
values('4' , '3' , 99);insert into score(course_id,student_id,score)
values('5' , '1' , 60);insert into score(course_id,student_id,score)
values('5' , '3' , 80);

3)课程表

添加数据的sql

insert into course(course_id,name,teacher_id)
values('4' , '音乐' , '4');insert into course(course_id,name,teacher_id)
values('5' , '美术' , '6');insert into course(course_id,name,teacher_id)
values('6' , '体育' , '5');

4)教师表里添加数据

添加数据的sql

-- 教师表:添加数据
insert into teacher(teacher_id,name)
values('4' , '新的');insert into teacher(teacher_id,name)
values('5' , '飞过');-- 这里的教师姓名是空值(null)
insert into teacher(teacher_id,name)
values('6' , null);

2. SQL的题

2.1 查询姓“猴”的学生名单

-- 查询姓“猴”的学生名单
select * from student WHERE name like '猴%';-- 查询姓名最后一个字是“猴”的学生
select * from student where name like '%猴';-- 查询姓名中拥有“猴”的学生名单、
select * from student where name like '%猴%';

2.2 查询课程编号为“2”的总成绩

-- 查询课程编号为“2”的总成绩
select sum(score)
from score
where course_id=2*
分析思路
select 查询结果 [总成绩:汇总函数sum]
from 从哪张表中查找数据[成绩表score]
where 查询条件 [课程号是2]
*/

2.3 查询选了课程的学生人数

-- 查询选了课程的学生人数
select count(distinct student_id) as studentNum
from score
/*
这个题目翻译成大白话就是:查询有多少人选了课程
select 学号,成绩表里学号有重复值需要去掉
from 从课程表查找score;
(distinct 去重,如果不去重的话,同一个人选了多门课也会叠加上)
*/

2.4 查询各科成绩最高和最低的分, 以如下的形式显示:课程号,最高分,最低分

-- 查询各科成绩最高和最低的分, 以如下的形式显示:课程号,最高分,最低分
select course_id, max(score),min(score)
from score
group by course_id
/*
分析思路
select 查询结果 [课程ID:是课程号的别名,最高分:max(成绩) ,最低分:min(成绩)]
from 从哪张表中查找数据 [成绩表score]
where 查询条件 [没有]
group by 分组 [各科成绩:也就是每门课程的成绩,需要按课程号分组];
*/

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

-- 查询每门课程被选修的学生数select course_id,count(student_id)
from score
group by course_id/*
分析思路
select 查询结果 [课程号,选修该课程的学生数:汇总函数count]
from 从哪张表中查找数据 [成绩表score]
where 查询条件 [没有]
group by 分组 [每门课程:按课程号分组];
*/

2.6 查询男生、女生人数

-- 查询男生、女生人数select sex,count(sex)
from student
group by sex
/*
分析思路
select 查询结果 [性别,对应性别的人数:汇总函数count]
from 从哪张表中查找数据 [性别在学生表中,所以查找的是学生表student]
where 查询条件 [没有]
group by 分组 [男生、女生人数:按性别分组]
having 对分组结果指定条件 [没有]
order by 对查询结果排序[没有];
*/

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

-- 查询平均成绩大于60分学生的学号和平均成绩
/*
题目翻译成大白话:
平均成绩:展开来说就是计算每个学生的平均成绩
这里涉及到“每个”就是要分组了
平均成绩大于60分,就是对分组结果指定条件
分析思路
select 查询结果 [学号,平均成绩:汇总函数avg(成绩)]
from 从哪张表中查找数据 [成绩在成绩表中,所以查找的是成绩表score]
where 查询条件 [没有]
group by 分组 [平均成绩:先按学号分组,再计算平均成绩]
having 对分组结果指定条件 [平均成绩大于60分]
*/select student_id,avg(score)
from score
group by student_id
having avg(score)>60

2.8 查询选修大于两门课程的学生学号

/*
翻译成大白话:
第1步,需要先计算出每个学生选修的课程数据,需要按学号分组
第2步,选修大于两门课程:也就是每个学生选修课程数目>2,对分组结果指定条件
分析思路
select 查询结果 [学号,每个学生选修课程数目:汇总函数count]
from 从哪张表中查找数据 [课程的学生学号:课程表score]
where 查询条件 [选修大于两门课程:需要先计算出每个学生选修了多少门课,
需要用分组,所以这里没有where子句]
group by 分组 [每个学生选修课程数目:按学号分组,然后用汇总函数count计算每个学号都选修了多少门课]
having 对分组结果指定条件 [至少选修两门课程:每个学生选修课程数目>2]
*/-- 查询选修大于两门课程的学生学号
select student_id,count(course_id)
from score
group by student_id
having count(course_id)>2

2.9 查询同名同性学生名单并统计同名人数

/*
翻译成大白话,问题解析:
1)查找出姓名相同的学生有谁,每个姓名相同学生的人数
查询结果:姓名,人数
条件:怎么算姓名相同?按姓名分组后人数大于等于2,因为同名的人数大于等于2
分析思路
select 查询结果 [姓名,人数:汇总函数count(*)]
from 从哪张表中查找数据 [学生表student]
where 查询条件 [没有]
group by 分组 [姓名相同:按姓名分组]
having 对分组结果指定条件 [姓名相同:count(*)>=2]
order by 对查询结果排序[没有];
*/
SELECT name,count(*) as personNum
from student
GROUP BY name
having count(*)>=2

2.10 查询分数少于75的课程以及分数,并按课程号从大到小排列


/*
分析思路
select 查询结果 [课程号][分数]
from 从哪张表中查找数据 [成绩表score]
where 查询条件 [成绩 <75]
group by 分组 [没有]
having 对分组结果指定条件 [没有]
order by 对查询结果排序[课程号从大到小排列:降序desc];
*/
select course_id,score
from score
where score < 75
order by course_id desc

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

/*
分析思路
select 查询结果 [课程号,平均成绩:汇总函数avg(成绩)]
from 从哪张表中查找数据 [成绩表score]
where 查询条件 [没有]
group by 分组 [每门课程:按课程号分组]
having 对分组结果指定条件 [没有]
order by 对查询结果排序[按平均成绩升序排序:asc,平均成绩相同时,按课程号降序排列:desc];
*/
select course_id,avg(score) as 平均成绩
from score
group by course_id
order by 平均成绩 asc, course_id desc

2.12 检索课程编号为“4”且分数小于等于90的学生学号,分数,结果按按分数降序排列


/*
分析思路
select 查询结果 []
from 从哪张表中查找数据 [成绩表score]
where 查询条件 [课程编号为“4”且分数小于等于90]
group by 分组 [没有]
having 对分组结果指定条件 []
order by 对查询结果排序[查询结果按按分数降序排列];
*/
select student_id,score
from score
where course_id = 4
and score<=90
ORDER BY score desc

2.13 统计每门课程的学生选修人数(超过2人的课程才统计)

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

/*
分析思路
select 查询结果 [要求输出课程号和选修人数]
from 从哪张表中查找数据 []
where 查询条件 []
group by 分组 [每门课程:按课程号分组]
having 对分组结果指定条件 [学生选修人数(超过2人的课程才统计):每门课程学生人数>2]
order by 对查询结果排序[查询结果按人数降序排序,若人数相同,按课程号升序排序];
*/
select course_id,count(student_id) as personNum
from score
group by course_id
HAVING count(student_id)>2
ORDER BY personNum desc,course_id asc

3. 复杂查询

3.1 查询存在不及格课程的同学的学号及其平均成绩

/*
分析思路
先分解题目:
1)[不及格课程]限制条件
2)[同学的学号及其平均成绩],也就是每个学生的平均成绩,显示学号,平均成绩
分析过程:
第1步:先查询存在不及格课程的同学的id
第2步:对第一步查询得到的id进行分组,统计
1)不及格课程
2)[存在不及格课程]:课程数目>0/*
第1步:得到存在不及格课程的同学的id
select 查询结果 [学号]
from 从哪张表中查找数据 [涉及到成绩:成绩表score]
where 查询条件 [score<60]
group by 分组 [每个学生的平均:按学号分组]
having 对分组结果指定条件 [不合格的成绩的数量大于1]
order by 对查询结果排序[没有];
*/select student_id
from score
where score<60
GROUP BY student_id
HAVING count(score)>0/*
第2步:对第一步查询得到的id进行分组,统计平均值
select 查询结果 [学号,平均成绩:汇总函数avg(成绩)]
from 从哪张表中查找数据 [涉及到成绩:成绩表score]
group by 分组 [每个学生的平均:按学号分组]
having 对分组结果指定条件 [限制条件:学号 in 第一步出来的学号]
*/
select student_id,avg(score) as 平均成绩
from score
group by student_id
having student_id in
(
select student_id
from score
where score<60
GROUP BY student_id
HAVING count(score)>0
)

3.2 查询所有课程成绩小于等于80分学生的学号、姓名

【知识点】子查询1.翻译成大白话
1)查询结果:学生学号,姓名
2)查询条件:所有课程成绩 <= 80 的学生,需要从成绩表里查找,用到子查询第1步,写子查询(所有课程成绩 <= 80 的学生(我们换一个角度来讲,就是不要存在成绩大于80的学生))
select 查询结果[学号]
from 从哪张表中查找数据[成绩表:score]
where 查询条件[成绩 < 80]
group by 分组[没有]
having 对分组结果指定条件[没有]
order by 对查询结果排序[没有]
limit 从查询结果中取出指定行[没有];select student_id
from score
WHERE score>80第2步,查询结果:学生学号,姓名,条件是对前面1步查到的学号取反select 查询结果[学号,姓名]
from 从哪张表中查找数据[学生表:student]
where 查询条件[用到运算符in](这里的in 的前面可以是where也可以是having,两个随便一个都行)
group by 分组[没有]
having 对分组结果指定条件[没有]
order by 对查询结果排序[没有]
limit 从查询结果中取出指定行[没有];
*/
select student_id,name
from student
where student_id not in
(
select student_id
from score
WHERE score>80
)

3.3 查询没有学全所有课的学生的学号、姓名|

select student_id,name
from student
where student_id not in
(
select student_id
from score
GROUP BY student_id
HAVING count(course_id)>(select count(course_id) from course)
)

3.4 查询出选修了四门课程的全部学生的学号和姓名

select student_id,name
from student
where student_id in
(
select student_id
from score
GROUP BY student_id
HAVING count(course_id)=4
)

3.5 2000年前出生的学生名单

/*
查找2000年前出生的学生名单
学生表中出生日期列的类型是date
*/
select student_id,name
from student
where year(date)<2000


4. topN问题

4.0 按课程号分组取成绩最大值所在行的数据

  • 我们可以使用分组(group by)和汇总函数得到每个组里的一个值(最大值,最小值,平均值等)。但是无法得到成绩最大值所在行的数据。按照下面的sql语句的话student_id查询出来的数据好像是错的(技术水平不错,暂时无法理解,如果知道并且愿意的话,请你留言一下)
select course_id,max(score) as 各科最大成绩,student_id
from score
group by course_id

select *
from score as a
where score=(
SELECT max(score)
from score as b
where b.course_id=a.course_id
);

这里特意改了一下课程“2”中其中的一个学生分数,发现有两个相同的最大分数也可以查得出来。

4.1 按课程号分组取成绩最小值所在行的数据

同样的使用关联子查询来实现

select *
from score as a
where score=(
SELECT min(score)
from score as b
where b.course_id=a.course_id
);

4.2 查询各科成绩前两名的记录

  1. 先使用order by子句按成绩降序排序(desc),然后使用limt子句返回topN(对应这个问题返回的成绩前两名)
select * from score where course_id =1
ORDER BY score DESC LIMIT 2
  1. 使用union all 将每组选出的数据合并到一起
(select * from score where course_id =1
ORDER BY score DESC LIMIT 2)
union all
(select * from score where course_id =2
ORDER BY score DESC LIMIT 2)
union all
(select * from score where course_id =3
ORDER BY score DESC LIMIT 2)
union all
(select * from score where course_id =4
ORDER BY score DESC LIMIT 2)
union all
(select * from score where course_id =5
ORDER BY score DESC LIMIT 2)


不过上面这样我感觉挺麻烦的,需要先知道有哪些课程编号,然后我想通过下面这种方式行不行,结果只返回了最大的两门课程的数据

select * from score where course_id in (select course_id from course)
ORDER BY score DESC LIMIT 2

5. 多表查询

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

select s.student_id,s.`name`,count(sc.course_id) as 选课数,sum(sc.score) as 总成绩
from student s
left join score sc
on s.student_id=sc.student_id
GROUP BY s.student_id

5.2 查询平均成绩大于70的所有学生的学号、姓名和平均成绩

select s.student_id,s.`name`,AVG(sc.score) as 平均成绩
from student s
left join score sc
on s.student_id=sc.student_id
GROUP BY s.student_id
HAVING avg(sc.score)>70

5.3 查询学生的选课情况:学号,姓名,课程号,课程名称

两种查询的结果都一样
1.
select s.student_id,s.`name`,c.course_id,c.`name`
from student s,score sc,course c
where s.student_id=sc.student_id and
sc.course_id=c.course_id2.
SELECT s.student_id,s.`name`,c.course_id,c.`name`
from student s
INNER JOIN score sc on s.student_id=sc.student_id
INNER JOIN course c on sc.course_id=c.course_id

5.4 查询出每门课程的及格人数和不及格人数

注意!注意!注意! 我面试的时候,有做过相似要求的题 QAQ

select course_id,
sum(case when score>=60 then 1else 0 end) as "及格人数",
sum(case when score< 60 then 1else 0end) as "不及格人数"
from score
GROUP BY course_id

5.5 使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计:各分数段人数,课程号和课程名称

select c.course_id,c.`name`,
sum(case when score between 85 and 100then 1 else 0 end) as '[100-85]',
sum(case when score>=75 and score<85then 1 else 0 end) as '(85-75]',
sum(case when score>=60 and score<75then 1 else 0 end) as '(75-60]',
sum(case when score<60 then 1 else 0 end) as '[<60]'
from score sc
RIGHT JOIN course c on sc.course_id=c.course_id
GROUP BY sc.course_id,c.`name`

RIGHT JOIN 右连接,不管course里面的数据在score有没有用到,都显示

select c.course_id,c.`name`,
sum(case when score between 85 and 100then 1 else 0 end) as '[100-85]',
sum(case when score>=75 and score<85then 1 else 0 end) as '(85-75]',
sum(case when score>=60 and score<75then 1 else 0 end) as '(75-60]',
sum(case when score<60 then 1 else 0 end) as '[<60]'
from score sc
left JOIN course c on sc.course_id=c.course_id
GROUP BY sc.course_id,c.`name`

left JOIN 左连接,以左边的为主,右边没有用到的不要

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

两种都可:
select s.student_id,s.`name`
from student s,score sc
where s.student_id=sc.student_id and sc.course_id=4 and sc.score>80 select s.student_id,s.`name`
from student s INNER JOIN score sc on s.student_id=sc.student_id
where sc.course_id=4 and sc.score>80

5.7. 行列如何互换

下面是学生的成绩表(表名score,列名:学号、课程号、成绩)

使用sql实现将该表行转列为下面的表结构

//第1步,使用常量列输出目标表的结构
select student_id,'课程号1','课程号2','课程号3','课程号4','课程号5'
from score;

//第2步,使用case表达式,替换常量列为对应的成绩
select student_id,
(case course_id when 1 then score else 0 end)as '课程号1',
(case course_id when 2 then score else 0 end)as '课程号2',
(case course_id when 3 then score else 0 end)as '课程号3',
(case course_id when 4 then score else 0 end)as '课程号4',
(case course_id when 5 then score else 0 end)as '课程号5'
from score
ORDER BY student_id asc//在这个查询结果中,每一行表示了某个学生某一门课程的成绩。
//比如第一行是'学号1'选修'课程号1'的成绩,而其他两列的'课程号2、3、4、5'成绩为0。
//如下方图所示

//第三步,分组 ,并使用最大值函数max取出下图学生每一个课程的最大值
select student_id,
max(case course_id when 1 then score else 0 end)as '课程号1',
max(case course_id when 2 then score else 0 end)as '课程号2',
max(case course_id when 3 then score else 0 end)as '课程号3'
from score
GROUP BY student_id

参考:https://blog.csdn.net/u010565545/article/details/100785261/

笔记----SQL语句相关推荐

  1. web安全学习笔记--sql语句(sql注入基础上)

    一.基础知和表内操作语法 1.sql语句对大小写不敏感!!! SELECT - 从数据库表中获取数据:select * from (columns/tables/databases); UPDATE ...

  2. MySQL笔记-SQL语句中可以使用单引号包裹任意类型

    最近看了个大佬写的PHP项目,在此膜拜下. 其中发下如下几句: public function autoUpdate($id,$data){$where = " where {$this-& ...

  3. mysql笔记 SQL语句简单的增删改查

    文章目录 mysql来源 navicat快捷键 mysql数据库语言分类 DQL 简单查询 条件查询 模糊查询 分组查询 使用limit字句 多表查询 在增删改句子中使用子查询 排序 显示当前使用数据 ...

  4. 数据库SQL语句学习笔记(3)-排序检索数据

    1.排序数据 如果不排序,数据一般将以它在底层表中出现的顺序显示,这有可能是数据最初添加到表中的顺序.但是如果数据随后进行过更新或删除,这个顺序就会受到DBMS重用回收存储空间的方式的影响. 子句:S ...

  5. oracle学习笔记(一)------oracle基础知识和基本sql语句

    最近一直在学习oracle,总结了一些学习笔记,我会陆续贴出来,和网友交流 ,希望能给一些初学者提供帮肋,也希望能有高手指点. oracle数据库逻辑结构   包括 表空间,段,区间和数据块     ...

  6. SQL语句从入门到精通之笔记大全

    SQL中有四种基本的DML操作:INSERT,SELECT,UPDATE和DELETE.由于这是大多数SQL用户经常用到的,我们有必要在此对它们进行说明. 下列语句部分是Mssql语句,不可以在acc ...

  7. 数据库SQL语句学习笔记(6)-使用函数处理数据

    1.SQL也可以用函数来处理数据,函数一般是在数据上执行的,为数据的转换和处理提供了方便.但是每一个数据库管理系统(DBMS)都有特定的函数,事实上,只有少数几个函数被所有的DBMS等同地支持.例如, ...

  8. mybatis笔记之一次插入多条数据sql语句写法

    mybatis笔记之一次插入多条数据sql语句写法

  9. 一图讲解一条sql语句的一生——《收获,不止Oracle》的读书笔记01

    其实也是<收获,不止Oracle>的读书笔记之一啦 微信读书可以看,数据库我觉得相通性还是比较大的,不管你用的哪种,都可以学学 难度的话,我才看到2.2 ,觉得本菜鸟还是可以看懂的. 说是 ...

最新文章

  1. cmd pc如何开多个微信_Win10下个人微信与企业微信多开
  2. mysql isam参数优化_MySQL MyISAM优化设置点滴
  3. java compareTo() 用法注意点
  4. 你犯了没?电脑最忌讳的18个小动作之三
  5. [团队开发]总结下Server 2008 + TeamFoundation Server 2008安装过程
  6. python16_day37【爬虫2】
  7. emc re 整改 超标_老刘工程师睡前故事5-EMC 辐射发射超标怎么办?
  8. windows下修改tomcat的startup.bat脚本文件后台运行
  9. Oracle RMAN 维护(二)--恢复目录的维护
  10. Chrome升级 76.0.3809.87后 GreenChrome无法使用的办法
  11. 【大数据之路-阿里巴巴大数据实践】第一篇 数据技术篇
  12. 登陆远程kvm_通过IPMI kvm控制台远程重装服务器系统
  13. 天地图 政府内网 代理
  14. 用计算机求方差的教案,《用科学计算器计算方差》教案.doc
  15. ye我们胜利了的shooow
  16. 虚拟机启动后一直黑屏的解决办法
  17. iOS开发长文--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook系统服务开发汇总
  18. 可达编程 单源最短路
  19. 一位IC验证工程师工作多年后的感悟
  20. Apache shiro 权限

热门文章

  1. 电路原理图中的各种地(数字地、模拟地、信号地、直流地、交流地、屏蔽地)的区别
  2. 哪些Apple设备支持这次系统更新?来看你的旧Apple设备支持最新系统吗
  3. 【Python入门指北】 Python计算机二级知识点
  4. 睢宁县微服务平台_微服务
  5. 曾辉机器人_6款国产SCARA机器人性能大比拼
  6. 使用HTML 5/CSS3五步快速制作便签贴特效
  7. 服务器托管到机房与放在本地的区别
  8. 无线充电比有线充电更慢吗?
  9. L2-040 哲哲打游戏(Python3)
  10. JAVA中的糕富帅技术