学生表 成绩表 课程表 教师表

article/2025/11/10 11:44:21

学生表:
Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别
课程表:
Course(c_id,c_name,t_id) – –课程编号, 课程名称, 教师编号
教师表:
Teacher(t_id,t_name) –教师编号,教师姓名
成绩表:
Score(s_id,c_id,s_s_score) –学生编号,课程编号,分数

根据以上信息按照下面要求写出对应的SQL语句。
ps:这些题考察SQL的编写能力,对于这类型的题目,需要你先把4张表之间的关联关系搞清楚了,最好的办法是自己在草稿纸上画关联图,然后再编写对应的SQL语句就比较容易了。

下图是我在草稿纸上画的这4张表的关系图,不好理解,你可以列举一些数据案例来辅助理解:

案例数据建立参考如下
表名和字段
–1.学生表
Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别

–2.课程表
Course(c_id,c_name,t_id) – –课程编号, 课程名称, 教师编号

–3.教师表
Teacher(t_id,t_name) –教师编号,教师姓名

–4.成绩表
Score(s_id,c_id,s_score) –学生编号,课程编号,分数

建立数据库、建表和插入数据

题目:思路、关键函数、解题语句、结果

知识点

语句表

MySQL 必知必会50题 训练笔记

建表和插入数据

新建数据库

数据库属性 utf8 -- UTF-8 Unicode

排序规则 utf8_unicode_ci

建表(创建查询,复制下方语句到查询中,运行即可)

-- 学生表
-- Student(s_id,s_name,s_birth,s_sex)
-- 学生编号,学生姓名, 出生年月,学生性别
CREATE TABLE `Student`(
`s_id` VARCHAR(20),
`s_name` VARCHAR(20) NOT NULL DEFAULT '',
`s_birth` VARCHAR(20) NOT NULL DEFAULT '',
`s_sex` VARCHAR(10) NOT NULL DEFAULT '',
PRIMARY KEY(`s_id`)
);
-- 课程表
-- Course(c_id,c_name,t_id) 
-- 课程编号, 课程名称, 教师编号
CREATE TABLE `Course`(
`c_id` VARCHAR(20),
`c_name` VARCHAR(20) NOT NULL DEFAULT '',
`t_id` VARCHAR(20) NOT NULL,
PRIMARY KEY(`c_id`)
);
-- 教师表
-- Teacher(t_id,t_name)
-- 教师编号,教师姓名
CREATE TABLE `Teacher`(
`t_id` VARCHAR(20),
`t_name` VARCHAR(20) NOT NULL DEFAULT '',
PRIMARY KEY(`t_id`)
);
-- 成绩表
-- Score(s_id,c_id,s_s_score) 
-- 学生编号,课程编号,分数
CREATE TABLE `Score`(
`s_id` VARCHAR(20),
`c_id` VARCHAR(20),
`s_score` INT(3),
PRIMARY KEY(`s_id`,`c_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' , '女');
-- 教师表数据
insert into Teacher values('t01' , '张三');
insert into Teacher values('t02' , '李四');
insert into Teacher values('t03' , '王五');
-- 课程表数据
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03');-- 成绩表数据
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);

 

刷新‘表‘就能看见建立的表了

题目

-- 1.查询课程编号为‘01’的课程比‘02’的课程成绩高的所有学生的学号、姓名和各自‘01’‘02’课程成绩

思路:通过学生编号将成绩表的课程‘01’成绩和课程‘02’成绩构建一张新表包含:学生编号、课程‘01’成绩、课程‘02成绩’

关键函数:SELECT...FROM...INNER JOIN...ON...WHERE...

解题语句:

SELECT a.s_id ,c.s_name,a.s_score '01',b.s_score '02'FROM
(SELECT s_id,c_id,s_score FROM score WHERE c_id='01')AS a
INNER JOIN
(SELECT s_id,c_id,s_score FROM score WHERE c_id='02')AS b ON a.s_id=b.s_id
INNER JOIN student AS c ON a.s_id=c.s_id
WHERE a.s_score>b.s_score;

结果:

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

思路:以学生学号进行分组,算平均成绩,筛选输出平均成绩大于60分的学生学号和平均成绩

关键函数:GROUP BY、 AVG()

解题语句

SELECT s_id,AVG(s_score)
FROM score
GROUP BY s_id HAVING AVG(s_score)>60

结果:

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

思路:学生表通过学生学号左关联成绩表,以学生学号进行分组,count函数计算选课数,sum函数计算总成绩,ifnull函数将由于左关联产生的成绩表中没有的同学数据null变成0

关键函数:GROUP BY、COUNT()、SUM()、IFNULL( , )、LEFT JOIN

解题语句

SELECT a.s_id,a.s_name,COUNT(b.c_id),SUM(IFNULL(b.s_score,0))
FROM student AS a
LEFT JOIN score AS b
ON a.s_id=b.s_id
GROUP BY s_id

结果:

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

思路:用like筛选老师姓名,避免姓名重复通过计算老师id来计算个数

关键函数:LIKE、COUNT

解题语句

SELECT COUNT(t_id)    
FROM teacher
WHERE t_name LIKE '张%'

结果:

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

思路1:多层嵌套、子查询

通过教师表查询得姓名为‘张三’的教师编号,用老师编号在课程表查询该老师教授的课程编号,通过课程编号在成绩表中查询没有该课程成绩的学生编号,最后通过学生编号在学生表中得出这些同学的学号姓名

关键函数:where、in

解题语句1

SELECT s_id,s_name FROM student  
WHERE s_id NOT IN(
SELECT s_id FROM score
WHERE c_id =
(SELECT c_id FROM course
WHERE t_id=
(SELECT t_id FROM teacher
WHERE t_name = '张三')))

结果:

思路2:成绩和课程表通过课程编号内连接,再与学生成绩表通过学生编号进行内连接。筛选处有‘张三’的课程成绩的学生编号,在学生表中选出学生编号不在上面选中的学生编号的学生姓名编号和姓名

关键函数:inner jion 、not in

解题语句2

SELECT s_id,s_name FROM student
WHERE s_id NOT IN(
SELECT a.s_id FROM score AS a
INNER JOIN course AS c ON c.c_id=a.c_id
INNER JOIN teacher AS d ON d.t_id=c.t_id
WHERE d.t_name='张三')

结果:

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

理解1:学过张三老师的课的学生信息

思路:构建一张表包含:学生学号、学生姓名、课程成绩、课程老师。再通过老师姓名筛选

用分组去重(虽然本题没有重复结果)

关键函数:inner jion

解题语句

SELECT st.s_id,st.s_name FROM student AS st 
INNER JOIN score AS s ON st.s_id=s.s_id
INNER JOIN course AS c ON s.c_id=c.c_id
INNER JOIN teacher AS t ON t.t_id=c.t_id
WHERE t.t_name ='张三'
GROUP BY st.s_id

结果:

理解2:学了张三老师所有课的学生信息

思路:构建一张表包含:学生学号、学生姓名、课程成绩、课程老师。通过老师姓名筛选。再选出学生所选课程数等于张三老师所教的课程数的学生信息

解题语句

SELECT st.s_id,st.s_name FROM student AS st 
INNER JOIN score AS s ON st.s_id=s.s_id
INNER JOIN course AS c ON s.c_id=c.c_id
INNER JOIN teacher AS t ON t.t_id=c.t_id
WHERE t.t_name ='张三' 
GROUP BY st.s_id
HAVING
COUNT(st.s_id) IN
(SELECT COUNT(c_name) FROM course 
INNER JOIN teacher 
ON course.t_id=teacher.t_id 
WHERE teacher.t_name='张三')

结果:

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

思路1:通过内连接将成绩表课程‘01’和课程‘02’的信息相连接得出新表,从学生表中获取学生编号在新表中的学生标号和姓名

关键函数:inner jion、in

解题语句1

SELECT s_id,s_name FROM student
WHERE s_id IN
(
SELECT a.s_id FROM
(SELECT s_id FROM score WHERE c_id='01')AS a
INNER JOIN
(SELECT s_id FROM score WHERE c_id='02')AS b
ON a.s_id=b.s_id
)

结果:

思路2:在学生表中选出满足两个条件的学生学号和学生姓名,条件1:有课程编号‘01’成绩的学生编号,条件2:有课程编号‘02’成绩的学生编号

关键函数:WHERE...IN...AND

解题语句2

SELECT s_id,s_name FROM student
WHERE s_id IN 
(SELECT s_id FROM score WHERE c_id='01')
AND s_id IN 
(SELECT s_id FROM score WHERE c_id='02')

结果:

-- 8、查询各门的总成绩、平均成绩和人数

关键函数:sum、avg、count

解题语句

SELECT c_id '课程编号',SUM(s_score) '总成绩',
AVG(s_score ) '平均成绩',COUNT(s_score) '人数'
FROM score 
GROUP BY c_id

结果:

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

思路:得出各同学课程成绩小于60分的课程数,统计各同学共学了几门课,选出二者相等的学生学号、姓名

关键函数:group_by、inner jion

解题语句

SELECT a.s_id,t.s_name FROM
(
SELECT s_id,COUNT(c_id) 'count'
FROM score
WHERE s_score<60
GROUP BY s_id
)AS a
INNER JOIN
(
SELECT s_id,COUNT(c_id) 'count'
FROM score
GROUP BY s_id
)AS b ON a.s_id=b.s_id
INNER JOIN student AS t ON a.s_id=t.s_id
WHERE a.count=b.count

结果:

-- 10、查询没有学全所有课的学生的学号、姓名

思路:将学生与成绩表通过学生学号左连接,计算每个学生的成绩数,选出小于课程总数的学生学号和姓名

关键函数:group_by、count、distinct、left jion

解题语句

SELECT st.s_id '学生学号',st.s_name '学生姓名'
FROM student AS st
LEFT JOIN score AS sc ON st.s_id=sc.s_id
GROUP BY st.s_id 
HAVING COUNT(DISTINCT sc.c_id)<(SELECT count(DISTINCT c_id) FROM course)

结果:

-- 11、查询至少有一门课程与学号为“01”的学生所学课程相同的其他同学的学号

思路:选出课程与‘01’学生学过的课程相同的学生学号,去重,去掉‘01’同学

关键函数:in、and

解题语句

SELECT s_id,s_name FROM student 
WHERE s_id in
(
SELECT DISTINCT s_id FROM score 
WHERE c_id in
(
SELECT c_id FROM score WHERE s_id='01'
)
AND s_id!='01'
)

结果:

-- 12、查询和“01”号同学所学课程完全相同的其他同学的学号

思路1:将学号不为‘01’的学生课程编号连接形成新的字段,选出与学号为‘01’的学生课程编号连接形成字段相同的学生学号

关键函数:group_concat、group by

解题语句1

SELECT s_id FROM score
WHERE s_id <>'01'
GROUP BY s_id
HAVING GROUP_CONCAT(c_id)=(
SELECT GROUP_CONCAT(c_id) FROM score WHERE s_id='01')

结果:

思路2:将学号不为‘01’的学生成绩表左连接学号为‘01’的学生成绩表,计算每一个学号不为‘01’的学生课程数,选出课程数和‘01’学生相同的学生学号

关键函数:left jion、group_by、count

解题语句

SELECT a.s_id FROM
(SELECT * FROM score WHERE s_id!='01') AS a
LEFT JOIN(SELECT * FROM score WHERE s_id='01')AS b
ON a.c_id=b.c_id
GROUP BY a.s_id
HAVING COUNT(b.s_id)=(SELECT COUNT(c_id) FROM score WHERE s_id='01') 

结果:

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

思路:成绩表和学生表通过学生学号关联得,查询学号满足以下:选出成绩表中小于60分的成绩,再通过学生学号分组,最后选出此表中大于一门成绩的学生生学号。

关键函数:AVG,INNER JOIN ,GROUP BY,COUNT

解题语句

SELECT a.s_id,a.s_name,AVG(b.s_score) FROM student AS a
INNER JOIN score AS b
ON a.s_id=b.s_id
WHERE a.s_id IN
(SELECT s_id FROM score AS a 
WHERE s_score<60
GROUP BY s_id
HAVING COUNT(s_score)>1)
GROUP BY a.s_id

结果:

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

思路:学生表和成绩表通过学生学号链接,用课程编号为‘01’和课程成绩小于60两个条件筛选,最后通过分数降序

关键函数:INNER JOIN,ORDER BY , DESC

解题语句

SELECT * FROM student AS a
INNER JOIN score AS b ON a.s_id=b.s_id
WHERE b.c_id='01'
AND b.s_score<60
ORDER BY b.s_score DESC

结果:

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

思路:用avg计算平均成绩,按照学生学号进行分组排序,利用max来显示每一门课的成绩(max函数没有实际意义,只是用来显示),用case when(课程编号为‘01’,输出成绩,否则输出null)得到每一门的课程成绩

关键函数:GROUP BY、ORDER BY、CASE WHEN THEN ELSE

解题语句

SELECT 
s_id,
MAX(CASE WHEN c_id='01' THEN s_score ELSE NULL END)'01',
MAX(CASE WHEN c_id='03' THEN s_score ELSE NULL END)'02',
MAX(CASE WHEN c_id='02' THEN s_score ELSE NULL END)'03',
AVG(s_score) 
FROM score
GROUP BY s_id
ORDER BY AVG(s_score) DESC

结果:

-- 18、查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率

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

思路:课程表和成绩表通过课程编号链接,通过课程编号分组,取出课程编号、课程名、最高分、最低分和平均分。将是否满足条件的分数通过case when函数变成01变量,求和便是符合条件的学生数,除以参与这一门考试的学生总数,便是各个分数段的概率

关键函数:group by,sum,case when ,count,max,min,avg,inner jion

解题语句:

SELECT b.c_id,b.c_name,
MAX(a.s_score)'最高分',MIN(a.s_score)'最低分',AVG(a.s_score)'平均分',
SUM(CASE WHEN a.s_score>=60 THEN 1 ELSE 0 END)/COUNT(a.s_id)'及格率',
SUM(CASE WHEN a.s_score>=70 AND a.s_score<80 THEN 1 ELSE 0 END)/COUNT(a.s_id)'中等率',
SUM(CASE WHEN a.s_score>=80 AND a.s_score<90 THEN 1 ELSE 0 END)/COUNT(a.s_id)'优良率',
SUM(CASE WHEN a.s_score>=90 THEN 1 ELSE 0 END)/COUNT(a.s_score)'优秀率'
FROM score AS a
INNER JOIN course AS b ON a.c_id=b.c_id
GROUP BY a.c_id

结果:

-- 19、按各科成绩进行排序,并显示排名

关键函数:rank()

解题语句:

SELECT s_score,rank() over(PARTITION by s_id ORDER BY s_score DESC) FROM score;

-- 20、查询学生的总成绩并进行排名

关键函数:sum、group by、order by

解题语句:

SELECT *,SUM(s_score) FROM score 
GROUP BY s_id 
ORDER BY SUM(s_score) DESC

结果:

-- 21 、查询不同老师所教不同课程平均分从高到低显示

思路:成绩表通过课程编号和课程表进行连接为了获得课程名,再通过老师编号和教师表进行连接为了获得老师名,通过课程编号或者课程名字进行分组,输出课程编号、课程名、教师名、平均分,最后按照平均分排序

关键函数:avg、INNER JOIN、GROUP BY、ORDER BY

解题语句:

SELECT a.c_id,b.c_name,c.t_name,AVG(a.s_score) FROM score AS a
INNER JOIN course AS b ON a.c_id=b.c_id
INNER JOIN teacher AS c ON b.t_id=c.t_id 
GROUP BY a.c_id
ORDER BY AVG(a.s_score) DESC

结果:

-- 22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩

思路:学生表和成绩表通过课程编号相连接,通过row_number函数增加一列课程成绩在该课程的排名,最后通过子查询筛选出排名,即增加的排名列数字为2,3的数据

关键函数:row_number、ORDER BY、INNER JOIN

解题语句:

SELECT * FROM 
(
SELECT b.s_id,b.s_name,b.s_birth,,b.s_sex,a.c_id,a.s_score,
row_number()over(PARTITION by a.c_id ORDER BY a.s_score DESC) m
FROM score AS a INNER JOIN student AS b ON a.s_id=b.s_id )
WHERE m IN(2,3)

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

思路:通过课程编号将成绩表和课程表连接,再通过课程编号分组,得出课程成绩和课程编号,通过case when函数将每个分数段的人数转换为0/1或者1/null 形式,通过sum(0/1)或者count(1/null)得出每个分数段的人数

关键函数:SUM/COUNT、case when、inner jion

解题语句:

SELECT a.c_id,b.c_name,
SUM(CASE WHEN a.s_score<60 THEN 1 ELSE 0 END) '不及格',
SUM(CASE WHEN a.s_score>=60 AND a.s_score<70 THEN 1 ELSE 0 END) '及格',
COUNT(CASE WHEN a.s_score>=70 AND a.s_score<85  THEN 1 ELSE NULL END) '良',
COUNT(CASE WHEN a.s_score>=85 THEN 1 ELSE NULL END) '优'
FROM score AS a
INNER JOIN course AS b ON a.c_id=b.c_id
GROUP BY a.c_id

结果:

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

关键函数:rank

解题语句:

SELECT s_id,AVG(s_score),rank() over(PARTITION by s_id ORDER BY AVG(s_score)DESC) FROM score

-- 25、查询各科成绩前三名的记录(不考虑成绩并列情况)

思路:学生表和成绩表通过课程编号相连接,通过row_number函数增加一列课程成绩在该课程的排名,最后通过子查询筛选出排名,即增加的排名列数字为1,2,3的数据

关键函数:row_number、ORDER BY、INNER JOIN

解题语句:

SELECT *
FROM (SELECT b.s_id,b.s_name,b.s_birth,,b.s_sex,a.c_id,a.s_score,
row_number()over(PARTITION by a.c_id ORDER BY a.s_score DESC) m
FROM score AS a INNER JOIN student AS b ON a.s_id=b.s_id ) a
WHERE m IN(1,2,3)

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

解题语句:

SELECT c_id,COUNT(c_id) FROM score
GROUP BY c_id

结果:

-- 27、查询出只有两门课程的全部学生的学号和姓名

思路1:通过学生学号将成绩表和学生表连接,通过学生学号分组,计算学生选课成绩的数量,用having筛选出数量为2的信息,输出学生学号和姓名

关键函数:LEFT JOIN、GROUP BY、HAVING、COUNT

解题语句1:

SELECT a.s_id,b.s_name,COUNT(a.c_id) FROM score AS a
LEFT JOIN student AS b ON a.s_id=b.s_id
GROUP BY a.s_id
HAVING COUNT(a.c_id)=2

结果:

思路2:成绩表通过学生学号分组,选出选课成绩为2的学生学号;通过子查询,在学生表中去的学生学号和姓名

关键函数:GROUP BY

解题语句2:

SELECT s_id,s_name FROM student
WHERE s_id IN(
(SELECT s_id FROM score
GROUP BY s_id
HAVING COUNT(c_id)=2)
)

结果:

-- 28、查询男生、女生人数

思路1:通过性别进行分组,计算每个性别人数

关键函数:GROUP BY、count

解题语句:

SELECT s_sex,COUNT(s_sex) 
FROM student 
GROUP BY s_sex

结果:

思路2:将性别变成01变量,通过sum/count得出每个性别人数

关键函数:case when、count、sum

解题语句:

SELECT 
SUM(CASE WHEN s_sex='男' THEN 1 ELSE 0 END)'男生个数',
count(CASE WHEN s_sex='女' THEN 1 ELSE NULL END) '女生个数'
FROM student

结果:

 

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

思路:用like进行字符串匹配

关键函数:like

解题语句:

SELECT * FROM student 
WHERE s_name LIKE '%风%'

结果:

 

-- 31、查询1990年出生的学生名单

思路1:用like进行字符串匹配的方法得到出生日期为1990年

关键函数:like

解题语句:

SELECT * FROM student 
WHERE s_birth LIKE '1990%'

结果:

思路2:用year函数去除日期中的年份,筛选出1990年的数据

关键函数:year

解题语句:

SELECT * FROM student
WHERE YEAR(s_birth)=1990

结果:

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

关键函数:INNER JOIN...ON、GROUP BY...HAVING

解题语句:

SELECT a.s_id,a.s_name,AVG(b.s_score) FROM student AS a
INNER JOIN score AS b ON a.s_id=b.s_id
GROUP BY b.s_id
HAVING AVG(b.s_score)>=85

结果:

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

关键函数:avg、select...from...group by...order by ...,...

解题语句:

SELECT c_id,AVG(s_score)
FROM score
GROUP BY c_id
ORDER BY AVG(s_score),c_id DESC

结果:

-- 34、查询课程名称为"数学",且分数低于60的学生姓名和分数

思路:将学生表(需要学生姓名)、成绩表(需要数学成绩)、课程表(需要课程名)连接起来筛选即可

关键函数:left jion....on

解题语句:

SELECT a.s_name,b.s_score FROM student AS a
LEFT JOIN score AS b
ON a.s_id=b.s_id
LEFT JOIN course AS c
ON b.c_id=c.c_id
WHERE c.c_name='数学'
AND b.s_score<60

结果:

 

-- 35、查询所有学生的课程及分数情况

思路1:需要形成的新表包括学生学号、学生姓名、各科成绩。将学生表左连接各科成绩表,各科成绩表通过将成绩表和课程表用课程编号连接后用课程名筛选后得出

关键函数:SELECT... FROM...LEFT JOIN...ON...

解题语句1:

SELECT a.s_id'学号',a.s_name'姓名',d.s_score'语文',e.s_score'数学',f.s_score'英语' 
FROM student AS a
LEFT JOIN
(SELECT b.s_id,c.c_name,b.s_score FROM score AS b
LEFT JOIN course AS c ON b.c_id=c.c_id WHERE c_name='语文')AS d
ON a.s_id=d.s_id
LEFT JOIN
(SELECT b.s_id,c.c_name,b.s_score FROM score AS b
LEFT JOIN course AS c ON b.c_id=c.c_id WHERE c_name='数学')AS e
ON a.s_id=e.s_id
LEFT JOIN
(SELECT b.s_id,c.c_name,b.s_score FROM score AS b
LEFT JOIN course AS c ON b.c_id=c.c_id WHERE c_name='英语')AS f
ON a.s_id=f.s_id

结果:

思路2:成绩表通过学生编号和学生表连接再通过课程编号和课程表连接,通过学生编号进行分组,通过case when输出各科成绩,判断课程名称并输出,由于输出只会输出第一条判断情况,所以用sum或者max

关键函数:MAX(CASE WHEN...THEN...ELSE NULL END)、SELECT... FROM...INNER JOIN...ON...

解题语句2:

SELECT c.s_id,c.s_name,
MAX(CASE WHEN b.c_name='语文' THEN a.s_score ELSE NULL END)'语文',
MAX(CASE WHEN b.c_name='数学' THEN a.s_score ELSE NULL END)'数学',
MAX(CASE WHEN b.c_name='英语' THEN a.s_score ELSE NULL END)'英语' 
FROM score AS a
INNER JOIN course AS b ON a.c_id=b.c_id
INNER JOIN student AS c ON a.s_id=c.s_id
GROUP BY c.s_id

结果:

-- 36、查询课程成绩在70分以上的学生姓名、课程名称和分数

思路:将学生表成绩表课程表相连接

关键函数:SELECT... FROM...LEFT JOIN...ON...WHERE...

解题语句:

SELECT a.s_name,c.c_name,b.s_score FROM student AS a
LEFT JOIN score AS b ON a.s_id=b.s_id
LEFT JOIN course AS c ON b.c_id=c.c_id 
WHERE b.s_score>70

结果:

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

关键函数:SELECT... FROM...INNER JOIN...ON...WHERE...ORDER BY...DESC

解题语句:

SELECT a.s_id,b.s_name,a.c_id,a.s_score FROM score AS a
INNER JOIN student AS b
ON a.s_id=b.s_id
WHERE a.s_score<60
ORDER BY a.c_id DESC

结果:

-- 38、查询课程编号为03且课程成绩在80分以上的学生的学号和姓名

关键函数:SELECT... FROM...INNER JOIN...ON...WHERE...AND...

解题语句:

SELECT a.s_id,b.s_name,a.s_score FROM score AS a
INNER JOIN student AS b
ON a.s_id=b.s_id
WHERE a.s_score>80
AND a.c_id='03'

结果:

-- 39、求每门课程的学生人数

解题语句:

SELECT c_id,COUNT(s_score) FROM score
GROUP BY c_id

结果:

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

思路:用窗口函数,rank

 

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

思路:从成绩表中通过用学生学号分组计算课程成绩数来选出至少学了有两门课的学生与成绩表内连接再通过学生学号和成绩分组筛选只有一个数据的学生学号

关键函数:INNER JOIN、GROUP BY、HAVING、COUNT(DISTINCT ...)

解题语句:

SELECT s_id FROM
(SELECT a.s_id,a.s_score FROM score AS a
INNER JOIN
(SELECT s_id FROM score
GROUP BY s_id HAVING COUNT(DISTINCT c_id)>1)AS b
ON a.s_id=b.s_id
GROUP BY a.s_id,a.s_score
)AS c
GROUP BY s_id HAVING COUNT(s_id)=1

结果:

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

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

关键函数:COUNT()、GROUP BY、HAVING、ORDER BY

解题语句:

SELECT c_id,COUNT(s_score) FROM score
GROUP BY c_id
HAVING COUNT(s_score)>5
ORDER BY COUNT(s_score) DESC,c_id

结果:

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

关键函数:COUNT()、GROUP BY、HAVING

解题语句:

SELECT s_id,COUNT(s_score) FROM score
GROUP BY s_id
HAVING COUNT(s_score)>=2

结果:

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

思路:由于要获得学生信息就通过学生学号将学生表和成绩表连接,将新表通过学生学号进行分组,筛选条件为学生课程数等于课程表中的课程数

关键函数:LEFT JOIN、GROUP BY、COUNT(DISTINCT ...)

解题语句:

SELECT * FROM student AS a
LEFT JOIN score AS b
ON a.s_id=b.s_id
GROUP BY a.s_id
HAVING COUNT(DISTINCT c_id) =( SELECT COUNT(c_id) FROM course)

结果:

-- 46、查询各学生的年龄(精确到月份)

关键函数:DATEDIFF()

解题语句:

SELECT s_id,s_birth,DATEDIFF('2020-5-20',s_birth)/365 FROM student

结果:

 

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

思路:用now()获得现在的时间month取出现在的月份,生日的月份等于通过round取余数加一则是下周过生日

关键函数:=MONTH()、date()、NOW()、%

解题语句:

SELECT * FROM student WHERE 
MONTH(s_birth)=MONTH(date(NOW()))%12+1

结果:


知识点:

1.inner jion、right jion、left jion的区别

inner join为“有效的连接”,就是根据on后面的关联条件,两张表中都有的数据才会显示

left join为主表全显示,连接后的表看on后面的选择条件,left join后面的条件,并不会影响左表的数据显示,左表数据会全部显示出来,连接的表如果没有数据,则全部显示为null

right join为“主表看on,后表全显”(右表数据不受影响),即右表数据全部显示,主表数据看on后面的选择条件

 

2.字符匹配

_代表一个字符, %代表0个及以上字符

开头是m m%

结尾是m %m

第二个字母为m _m%

非首字母字母有m _%m%

 

3.rank,dense_rankrow_number的区别

rank(跳跃排序)

分数 排名

92 1

82 2

82 2

67 4

dense_rank(连续排序)

分数 排名

92 1

82 2

82 2

67 3

row_number(无重复值排序)

分数 排名

92 1

82 2

82 3

67 4

 


语句表:

1、插入数据:

insert into 表名 values( ) #输入的值要跟原表对应

insert into Teacher values('02' , '李四')

 

2、查询表中的数据:

select * from 表名 # *号代表取全部列的数据

select * from student

 

select 指定列 from 表名

SELECT t_id,s_score FROM score

 

查询表中数据的统计量:min、max、avg、count、sum,

select avg(列名) from 表名

SELECT c_id '课程编号',SUM(s_score) '总成绩',AVG(s_score ) '平均成绩',COUNT(s_score) '人数' FROM score

GROUP BY c_id

 

条件查询:

select 指定列 from 表名 where 条件

SELECT s_id FROM score WHERE s_id <>'01'

条件符号:

(1)>大于 ;<小于; =等于; <>和!=不等于

(2)like 字符匹配 select * from teacher where t_name like '张%'

(3)between...and 区间 SELECT * FROM score WHERE s_score BETWEEN 70 AND 90

(4)in 指定数据集作为条件,也常用于子查询

 

3、GROUP BY 语句

根据一个或多个列对结果集进行分组,分组后的输出的统计量是每一组的统计量

SELECT 列名或统计量 FROM 表名 GROUP BY 列名

SELECT c_id,SUM(s_score),AVG(s_score ),COUNT(s_score)

FROM score

GROUP BY c_id

 

GROUP BY后的条件查询用having

 

4、ORDER BY 语句

排序

SELECT *,SUM(s_score) FROM score GROUP BY s_id ORDER BY SUM(s_score) DESC

 

5、year、month、day、now语句

用来从日期中提取需要的年/月/日

SELECT * FROM student WHERE YEAR(s_birth)=1990;

SELECT * FROM student WHERE MONTH(s_birth)=01;

SELECT * FROM student WHERE DAY(s_birth)='01';

条件可以用数字或者字符串

日期类型可以是YYYY-MM-DD、YYYYMMDD、YYYY/MM/DD

2020-05-20、20200520、2020/05/20

注意:对于YYYYMMDD这种格式日期,0不能少,一月份必须是01不能是1,但年份可以是后两位,即格式为YYMMDD

now()

获得当前时间有时分秒

 

6、LIMIT语句

用于选取第几行数据,SQL从0开始计数

SELECT c_id FROM score

LIMIT 0,1 #表示从0开始(第一行开始),选取第一行数据

 

7、DATEDIFF语句

用于计算日期间隔

SELECT s_id,s_birth,DATEDIFF('2020-5-20',s_birth)/365 FROM student

 

 


http://chatgpt.dhexx.cn/article/aqQ03EnV.shtml

相关文章

MySQL基础 创建学生表实现查询基础功能

一. 创建学生表 1.进入MySQL WIN R 输入cmd 输入mysql -u root -p 输入密码进入mysql 2. 输入show databases; 查询现有数据库 选择一个数据库 use 数据库名称 创建一个学生表 create table stu( id int ,-- 编号 name varchar(10),-- 姓名 gender char(1)…

数据库学生表

文章目录 学生表建立学生表&#xff1a;建表过程中出现的错误&#xff1a; 插入数据 课程表建立课程表&#xff1a;插入数据 选课表建立选课表插入数据建表过程中出现的错误&#xff1a; 修改基本表增加属性列&#xff1a;修改数据类型&#xff1a;增加约束条件&#xff1a;删除…

LDA理解

LDA 过程&#xff1a; 希拉里邮件lda建模&#xff1a;

LDA步骤

自己学习备忘用。节选自(1条消息) LDA原理小结_Sual-CSDN博客_lda原理

NLP: LDA主题模型

Essence本质&#xff1a;LDA模型主要包括主题分布θ和词语分布&#xff0c; 主题分布&#xff1a;各个主题在文档中出现的概率分布。词语分布&#xff1a;各个词语在某个主题下出现的概率分布。 pLSA模型中这两个分布是固定的&#xff0c;由期望最大化EM(Expectation Maximiz…

LDA算法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、LDA是什么&#xff1f;二、公式推导三、PCA和LDA的区别总结 前言 线性判别分析&#xff08;LDA&#xff09;是一种有监督学习算法&#xff0c;同时经常被用…

自然语言处理7——LDA

文章目录 1. PLSA、共轭先验分布&#xff1b;LDA主题模型原理1.1 PLSA1.2 共轭先验分布1.2.1 共轭先验分布的参数确定1.2.2 常见的共轭先验分布 1.3 LDA主题模型原理 2. LDA应用场景3. LDA优缺点4. LDA 在sklearn中的参数学习5. 使用LDA生成主题特征&#xff0c;在之前特征的基…

matlab lda数据降维,LDA有标签数据降维

之前无标签数据降维PCA,那么像下图带有标签数据,如果用PCA降维将会投影到v轴上,这个投影方差最大,数据将变成不可分状态,LDA将把数据投影加上已有分类这个变量,将数据投影到u轴上 假设原数据分成n类,用矩阵Di表示i类数据,均值向量mi,将设将数据投影到向量w上后,均值分…

LDA模型,主题聚类模型

自然语言处理--LDA主题聚类模型 LDA模型算法简介&#xff1a; 算法 的输入是一个文档的集合D{d1, d2, d3, ... , dn}&#xff0c;同时还需要聚类的类别数量m&#xff1b;然后会算法会将每一篇文档 di 在 所有Topic上的一个概率值p&#xff1b;这样每篇文档都会得到一个概率的集…

LDA主题模型笔记

Table of Contents 1、写在前面 2、数学知识 3、文本建模 4.LDA主题模型实战 1、写在前面 在机器学习领域&#xff0c;关于LDA有两种含义&#xff0c;一是线性判别分析&#xff08;Linear Discriminant Analysis&#xff09;&#xff0c;是一种经典的降维学习方法&#xf…

LDA 主题模型

背景 我们生活中总是产生大量的文本&#xff0c;分析这些观察到的语料库是如何生成的就需要对文本进行建模。常见的文本建模方法包括&#xff1a;Unigram、PLSA、LDA 、词向量模型&#xff08;CBOW、Skip-gram&#xff09;等。LDA模型是一种主题模型&#xff08;topic model&a…

lda php,LDA主题分析代码实现

主题文本分析&#xff1a; 首先读取txt文本&#xff0c;并删除stop_list中存放的停止词汇 f open(..\\LDA_test.txt) texts [[word for word in line.strip().lower().split() if word not in stop_list] for line in f] print(Text ) pprint(texts)  #输出格式处理好的文本…

详解 LDA

详解 LDA 详解 LDA基本概念什么是LDALDA 核心思想LDA 简单二分类实例 实现步骤&#xff08;python&#xff09;第一步 标准化处理第二步 计算每一类别特征的均值向量第三步 计算类间散布矩阵S(B)和类内散布矩阵S(W)第四步 计算矩阵S(W)^(-1)S(B)的特征值和对应的特征向量第五步…

LDA 指南

『本文转自&#xff1a;https://wdxtub.com/2017/05/03/lda-guide/』 LDA 作为文本分析中非常有用的算法&#xff0c;无论是在学术界还是工业界都已被广泛运用。本文是写给自己的 LDA 理解指南。 更新历史 2017.05.03: 完成初稿 关于 LDA 算法&#xff0c;网上的资料不胜枚举…

LDA

关于降维算法 机器学习领域中所谓的降维就是指采用某种映射方法&#xff0c;将原高维空间中的数据点映射到低维度的空间中。降维的本质是学习一个映射函数 f : x->y&#xff0c;其中x是原始数据点的表达&#xff0c;目前最多使用向量表达形式。 y是数据点映射后的低维向量表…

LDA详解

【几个问题待解决&#xff1a;1.LDA的先计算联合概率体现在哪里 2.对于theta 的采样的理解&#xff0c;下文中的theta1 &#xff0c;theta2等其实是指theta向量中的第一个&#xff0c;第二个等&#xff0c;也就是不同文章的不同单词的主题&#xff0c;固定其他&#xff0c;分别…

LDA的通俗理解

1.PLSA模型 在讲解LDA模型之前&#xff0c;与LDA模型最为接近的便是下面要阐述的这个pLSA模型&#xff0c;给pLSA加上贝叶斯框架&#xff0c;便是LDA。 1.1什么是pLSA模型 我们假定一篇文档只由一个主题生成&#xff0c;可实际中&#xff0c;一篇文章往往有多个主题&#xff…

LDA模型详解

LDA是自然语言处理中非常常用的一个主题模型&#xff0c;全称是隐含狄利克雷分布&#xff08;Latent Dirichlet Allocation&#xff09;&#xff0c;简称LDA。作用是将文档集中每篇文档的主题以概率分布的形式给出&#xff0c;然后通过分析分到同一主题下的文档抽取其实际的主题…

机器学习——LDA(线性判别分析)与人脸识别

忆如完整项目/代码详见github&#xff1a;https://github.com/yiru1225&#xff08;转载标明出处 勿白嫖 star for projects thanks&#xff09; 目录 系列文章目录 一、LDA的概念与原理 1.LDA简介 2.LDA算法模型 3.LDA的不足与优化 二、LDA运用于人脸识别 1.预处理 1…

线性判别分析(LDA)详解

入门小菜鸟&#xff0c;希望像做笔记记录自己学的东西&#xff0c;也希望能帮助到同样入门的人&#xff0c;更希望大佬们帮忙纠错啦~侵权立删。 目录 一、LDA简介 二、数学原理&#xff08;以二分类为例子&#xff09; 1、设定 2、每一类的均值和方差 3、目标函数 4、目标…