新视野大学英语3课后习题答案(MySQL实验)

 2025-07-18 06:45:01  阅读 180  评论 0

摘要:概述今天主要用一个实验来介绍一下在使用行转列的过程及相关实验。下面演示一下。创建表这里我用一个比较简单的例子来说明,也是行转列的经典例子,就是学生的成绩三张表:学生表、课程表、成绩表1、学生表就简单一点,学生学号、学生姓名两个字段CREATE TABLE `student` ( `

概述

今天主要用一个实验来介绍一下在使用行转列的过程及相关实验。下面演示一下。


创建表

这里我用一个比较简单的例子来说明,也是行转列的经典例子,就是学生的成绩三张表:学生表、课程表、成绩表

1、学生表

就简单一点,学生学号、学生姓名两个字段

CREATE TABLE `student` (
 `stuid` VARCHAR(16) NOT NULL COMMENT '学号',
 `stunm` VARCHAR(20) NOT NULL COMMENT '学生姓名',
 PRIMARY KEY (`stuid`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

2、课程表

课程编号、课程名

CREATE TABLE `courses` (
 `courseno` VARCHAR(20) NOT NULL,
 `coursenm` VARCHAR(100) NOT NULL,
 PRIMARY KEY (`courseno`)
)
COMMENT='课程表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

3、成绩表

学生学号、课程号、成绩

CREATE TABLE `score` (
 `stuid` VARCHAR(16) NOT NULL,
 `courseno` VARCHAR(20) NOT NULL,
 `scores` FLOAT NULL DEFAULT NULL,
 PRIMARY KEY (`stuid`, `courseno`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

以上就是数据库表的结构了,这里没有建立外键,但是根据表的结构,可以清楚的看到成绩表中的学号和课程号是与学生表、课程表分别关联起来的。

MySQL实验--静态行转列->动态行转列->存储过程使用行转列


基础数据准备

/*学生表数据*/
Insert Into student (stuid, stunm) Values('1001', '张三');
Insert Into student (stuid, stunm) Values('1002', '李四');
Insert Into student (stuid, stunm) Values('1003', '赵二');
Insert Into student (stuid, stunm) Values('1004', '王五');
Insert Into student (stuid, stunm) Values('1005', '刘青');
Insert Into student (stuid, stunm) Values('1006', '周明');
/*课程表数据*/
Insert Into courses (courseno, coursenm) Values('C001', '大学语文');
Insert Into courses (courseno, coursenm) Values('C002', '新视野英语');
Insert Into courses (courseno, coursenm) Values('C003', '离散数学');
Insert Into courses (courseno, coursenm) Values('C004', '概率论与数理统计');
Insert Into courses (courseno, coursenm) Values('C005', '线性代数');
Insert Into courses (courseno, coursenm) Values('C006', '高等数学(一)');
Insert Into courses (courseno, coursenm) Values('C007', '高等数学(二)');
/*成绩表数据*/
Insert Into score(stuid, courseno, scores) Values('1001', 'C001', 67);
Insert Into score(stuid, courseno, scores) Values('1002', 'C001', 68);
Insert Into score(stuid, courseno, scores) Values('1003', 'C001', 69);
Insert Into score(stuid, courseno, scores) Values('1004', 'C001', 70);
Insert Into score(stuid, courseno, scores) Values('1005', 'C001', 71);
Insert Into score(stuid, courseno, scores) Values('1006', 'C001', 72);
Insert Into score(stuid, courseno, scores) Values('1001', 'C002', 87);
Insert Into score(stuid, courseno, scores) Values('1002', 'C002', 88);
Insert Into score(stuid, courseno, scores) Values('1003', 'C002', 89);
Insert Into score(stuid, courseno, scores) Values('1004', 'C002', 90);
Insert Into score(stuid, courseno, scores) Values('1005', 'C002', 91);
Insert Into score(stuid, courseno, scores) Values('1006', 'C002', 92);
Insert Into score(stuid, courseno, scores) Values('1001', 'C003', 83);
Insert Into score(stuid, courseno, scores) Values('1002', 'C003', 84);
Insert Into score(stuid, courseno, scores) Values('1003', 'C003', 85);
Insert Into score(stuid, courseno, scores) Values('1004', 'C003', 86);
Insert Into score(stuid, courseno, scores) Values('1005', 'C003', 87);
Insert Into score(stuid, courseno, scores) Values('1006', 'C003', 88);
Insert Into score(stuid, courseno, scores) Values('1001', 'C004', 88);
Insert Into score(stuid, courseno, scores) Values('1002', 'C004', 89);
Insert Into score(stuid, courseno, scores) Values('1003', 'C004', 90);
Insert Into score(stuid, courseno, scores) Values('1004', 'C004', 91);
Insert Into score(stuid, courseno, scores) Values('1005', 'C004', 92);
Insert Into score(stuid, courseno, scores) Values('1006', 'C004', 93);
Insert Into score(stuid, courseno, scores) Values('1001', 'C005', 77);
Insert Into score(stuid, courseno, scores) Values('1002', 'C005', 78);
Insert Into score(stuid, courseno, scores) Values('1003', 'C005', 79);
Insert Into score(stuid, courseno, scores) Values('1004', 'C005', 80);
Insert Into score(stuid, courseno, scores) Values('1005', 'C005', 81);
Insert Into score(stuid, courseno, scores) Values('1006', 'C005', 82);
Insert Into score(stuid, courseno, scores) Values('1001', 'C006', 77);
Insert Into score(stuid, courseno, scores) Values('1002', 'C006', 78);
Insert Into score(stuid, courseno, scores) Values('1003', 'C006', 79);
Insert Into score(stuid, courseno, scores) Values('1004', 'C006', 80);
Insert Into score(stuid, courseno, scores) Values('1005', 'C006', 81);
Insert Into score(stuid, courseno, scores) Values('1006', 'C006', 82);

MySQL实验--静态行转列->动态行转列->存储过程使用行转列

测试数据


纵列效果

我们一般进行成绩查询的时候看到的是这种纵列的结果

mysql> select s.stuid,s.stunm,c.coursenm,sc.scores from student s,courses c ,score sc limit 20;

MySQL实验--静态行转列->动态行转列->存储过程使用行转列

如果要把分数这一行跟课程这一列倒转怎么办呢?


静态行转列

Select st.stuid, st.stunm, 
 MAX(CASE c.coursenm WHEN '大学语文' THEN s.scores ELSE 0 END ) '大学语文',
 MAX(CASE c.coursenm WHEN '新视野英语' THEN ifnull(s.scores,0) ELSE 0 END ) '新视野英语', 
 MAX(CASE c.coursenm WHEN '离散数学' THEN ifnull(s.scores,0) ELSE 0 END ) '离散数学',
 MAX(CASE c.coursenm WHEN '概率论与数理统计' THEN ifnull(s.scores,0) ELSE 0 END ) '概率论与数理统计',
 MAX(CASE c.coursenm WHEN '线性代数' THEN ifnull(s.scores,0) ELSE 0 END ) '线性代数',
 MAX(CASE c.coursenm WHEN '高等数学(一)' THEN ifnull(s.scores,0) ELSE 0 END ) '高等数学(一)',
 MAX(CASE c.coursenm WHEN '高等数学(二)' THEN ifnull(s.scores,0) ELSE 0 END ) '高等数学(二)'
From Student st
Left Join score s On st.stuid = s.stuid
Left Join courses c On c.courseno = s.courseno
Group by st.stuid

看上面的语句可以看出,我们是在知道固定的几门课程之后,可以使用

MAX(CASE c.coursenm WHEN '线性代数' THEN ifnull(s.scores,0) ELSE 0 END ) '线性代数',

这样的语句来实现行转列

MySQL实验--静态行转列->动态行转列->存储过程使用行转列

但课程不仅仅这几门,如果用上面的语句去写,第一要确定有多少课程,这么多课程的课程名要再拿出来,那样的话写一个查询语句下来,可是要写很多了。


动态行转列

如何进行动态行转列呢?首先我们要动态获取这样的语句

MAX(CASE c.coursenm WHEN '大学语文' THEN s.scores ELSE 0 END ) '大学语文',
MAX(CASE c.coursenm WHEN '线性代数' THEN ifnull(s.scores,0) ELSE 0 END ) '线性代数', 
MAX(CASE c.coursenm WHEN '离散数学' THEN ifnull(s.scores,0) ELSE 0 END ) '离散数学'

而不是像上面那样一句句写出来,这里就要用到SQL语句拼接了。具体就是下面的语句

SELECT
	GROUP_CONCAT( DISTINCT CONCAT( 'MAX(IF(c.coursenm = ''', c.coursenm, ''', s.scores, 0)) AS ''', c.coursenm, '''' ) ) 
FROM
	courses c;

MySQL实验--静态行转列->动态行转列->存储过程使用行转列

上面就是进行行转列查询要用的语句,那样就不用知道多少课程和这些课程的名字,只要这样几行代码便可以得到动态的列了。

动态的列是拿到了,那如何再结合SQL语句进行查询得到结果呢?

这里要说明一点,因为用到了拼接函数,如果像上面的查询语句,只是把那几行语句替换掉,也就是下面这样

Select st.stuid, st.stunm, 
(
 SELECT
 GROUP_CONCAT(DISTINCT
 CONCAT(
 'MAX(IF(c.coursenm = ''',
 c.coursenm,
 ''', s.scores, NULL)) AS ',
 c.coursenm
 )
 )
 FROM courses c
)
From Student st
Left Join score s On st.stuid = s.stuid
Left Join courses c On c.courseno = s.courseno
Group by st.stuid;

然而得到的结果却是这样的

MySQL实验--静态行转列->动态行转列->存储过程使用行转列

最终结果如下:

像普通的那些语句那样进行声明,将语句拼接完整之后,再执行

--动态行转列
SET @SQL = NULL;
SELECT
	GROUP_CONCAT( DISTINCT CONCAT( 'MAX(IF(c.coursenm = ''', c.coursenm, ''', s.scores, 0)) AS ''', c.coursenm, '''' ) ) INTO @SQL 
FROM
	courses c;
 
SET @SQL = CONCAT( 'Select st.stuid, st.stunm, ', @SQL, ' From Student st 
	Left Join score s On st.stuid = s.stuid
	Left Join courses c On c.courseno = s.courseno
Group by st.stuid' );
PREPARE stmt 
FROM
	@SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

MySQL实验--静态行转列->动态行转列->存储过程使用行转列

这样就实现了动态行转列的目的了。而且我们不用知道多少课程,也无需把这些课程名一一列出来。当然这个语句拼接中的查询可以加入条件查询。


存储过程--动态行转列

用存储过程的好处是,方便我们调用,相当于一个函数,其他可能也是类似的查询不需再重复写代码,直接调存储过程就好,还能随心所欲的加上if条件判断

创建存储过程的语句我就不多写了,这里把上面的查询语句直接放到创建存储过程的begin和end直接就可以了,如下:

DELIMITER && 
drop procedure if exists SP_QueryData;
Create Procedure SP_QueryData(IN stuid varchar(16))
READS SQL DATA 
BEGIN
 
SET @sql = NULL;
SET @stuid = NULL;
SELECT
 GROUP_CONCAT(DISTINCT
 CONCAT(
 'MAX(IF(c.coursenm = ''',
 c.coursenm,
 ''', s.scores, 0)) AS ''',
 c.coursenm, '\''
 )
 ) INTO @sql
FROM courses c;
 
SET @sql = CONCAT('Select st.stuid, st.stunm, ', @sql, 
 ' From Student st 
 Left Join score s On st.stuid = s.stuid
 Left Join courses c On c.courseno = s.courseno');
 
IF stuid is not null and stuid <> '' then
SET @stuid = stuid;
SET @sql = CONCAT(@sql, ' Where st.stuid = \'', @stuid, '\'');
END IF; 
 
SET @sql = CONCAT(@sql, ' Group by st.stuid');
 
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
 
END && 
DELIMITER ;

MySQL实验--静态行转列->动态行转列->存储过程使用行转列

调用存储过程:

CALL `SP_QueryData`('1001');

得到如下结果

MySQL实验--静态行转列->动态行转列->存储过程使用行转列

也可以直接传个空串过去

CALL `SP_QueryData`('');

同样得到我们想要的结果

MySQL实验--静态行转列->动态行转列->存储过程使用行转列


总结

以上就是mysql数据库行转列实现的过程中的内容,相对来说,我觉得,这里写的很清晰了,所以只要你有耐心看完并认真研究的话,这个内容对你的行转列还是有很大帮助的,建议大家百忙之中做下实验。后面会分享更多DBA方面的内容,感兴趣的朋友可以关注一下~

MySQL实验--静态行转列->动态行转列->存储过程使用行转列

版权声明:我们致力于保护作者版权,注重分享,被刊用文章【新视野大学英语3课后习题答案(MySQL实验)】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!;

原文链接:https://www.yxiso.com/fangfa/1849606.html

发表评论:

关于我们
院校搜的目标不仅是为用户提供数据和信息,更是成为每一位学子梦想实现的桥梁。我们相信,通过准确的信息与专业的指导,每一位学子都能找到属于自己的教育之路,迈向成功的未来。助力每一个梦想,实现更美好的未来!
联系方式
电话:
地址:广东省中山市
Email:beimuxi@protonmail.com

Copyright © 2022 院校搜 Inc. 保留所有权利。 Powered by BEIMUCMS 3.0.3

页面耗时0.0366秒, 内存占用1.94 MB, 访问数据库23次

陕ICP备14005772号-15