最近工作中用到了好几次列转行,索性做个小总结,下面这篇文章主要给大家介绍了关于关系型数据库如何列转行的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
目录
一、需求:二、如何实现1)首先看我们的静态SQL2)那么就有人问了,如果我有100门课程不是要写100次名称,这也太麻烦了?3)这样每次都写一长串结构化查询语言也很麻烦?总结
一、需求:
有三张表,学生表、成绩表和课程表,我们可以通过连表查询出学生姓名、课程及对应的成绩:所需表结构化查询语言
- -
-学生用的表格结构
- -
如果存在“学生”,则删除表;
创建表"学生"(
` s_id` varchar(20) NOT NULL DEFAULT ,
` s _ name ` varchar(20)NOT NULL DEFAULT ,
` s _ birth ` varchar(20)NOT NULL DEFAULT ,
` s _ sex ` varchar(10)NOT NULL DEFAULT ,
主键(` s_id `)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
- -
-学生记录
- -
插入学生值( 01 ,赵雷, 1990-01-01, 男);
插入学生值( 02 ,钱电, 1990-12-21, 男);
插入学生值( 03 ,孙风, 1990-05-20, 男);
插入学生值( 04 ,李云, 1990-08-06, 男);
插入学生值( 05 ,周梅, 1991-12-01, 女);
插入学生值( 06 ,吴兰, 1992-03-01, 女);
插入学生值( 07 ,郑竹, 1989-07-01, 女);
插入学生值( 08 ,王菊, 1990-01-20, 女);
- -
-课程的表格结构
- -
如果存在"课程",则删除表格;
创建表格"课程"(
` c_id` varchar(20) NOT NULL DEFAULT ,
` c _ name ` varchar(20)NOT NULL DEFAULT ,
` t_id` varchar(20)不为空,
主键(` c_id `)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
- -
-当然是记录
- -
插入课程值( 01 ,语文, 02);
插入课程值( 02 ,数学, 01);
插入课程值(03,英语, 03);
- -
-分数的表格结构
- -
如果存在"分数",则删除表格;
创建表格"分数"(
` s_id` varchar(20) NOT NULL DEFAULT ,
` c_id` varchar(20) NOT NULL DEFAULT ,
` s_score` int(3)默认为空,
主键(` s_id ,` c_id )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
- -
-得分记录
- -
插入"分数"值("01"、"01"、"80");
插入"分数"值("01"、"02"、"90");
插入"分数"值("01"、"03"、"99");
插入"分数"值("02"、"01"、"70");
插入"分数"值("02"、"02"、"60");
插入"分数"值("02"、"03"、"80");
插入"分数"值("03"、"01"、"80");
插入"分数"值("03"、"02"、"80");
插入"分数"值("03"、"03"、"80");
插入"分数"值("04"、"01"、"50");
插入"分数"值("04"、"02"、"30");
插入"分数"值("04"、"03"、"20");
插入"分数"值("05"、"01"、"76");
插入"分数"值("05"、"02"、"87");
插入"分数"值("06"、"01"、"31");
插入"分数"值("06"、"03"、"34");
插入"分数"值("07"、"02"、"89");
插入"分数"值("07"、"03"、"98");
选择s . s . id,s . s . name,c . c . name,sc分数
来自学生s
供应链标识=供应链标识的左连接分数南卡罗来纳州
在c.c_id=sc.c_id上向左加入课程c
好的,现在呢我们要把课程名称呢变成横行呢?
二、如何实现
1)首先看我们的静态SQL关联成绩表课程表查询学生各科课程成绩
选择s . s . id,s . s . name,c . c . name,sc分数
来自学生s
供应链标识=供应链标识的左连接分数南卡罗来纳州
在c.c_id=sc.c_id上左加入课程c;
如果(s1、s2、s3)表达式,类似三木运算符取值,s1值为真取s2值,假取s3个值,最后可得到某一科成绩
SELECT p . s . id,p . s . name,p . c . name,p . c . name=数学,
IF(p.c_name=数学,p.c_name,NULL)c_name,IF(p.c_name=数学,p.s_score,NULL)s_score
来自(
选择s . s . id,s . s . name,c . c . name,sc分数
来自学生s
供应链标识=供应链标识的左连接分数南卡罗来纳州
c.c_id=sc.c_id)p上左加入课程c;
然后我们分组且用马克斯(男子名等于马克西米利安)函数获取每个学生的数学课程的成绩,替换这一课的字段名称
选择p.s_id,
附:姓名,
MAX(IF(p.c_name=数学,p.s_score,NULL))为数学
来自(
选择s . s . id,s . s . name,c . c . name,sc分数
来自学生s
供应链标识=供应链标识的左连接分数南卡罗来纳州
在c.c_id=sc.c_id)p上向左加入航向c
按公共服务标识分组;
获取所有人各科成绩
选择p.s_id,
附:姓名,
MAX(IF(p.c_name=数学,p.s_score,NULL))为数学,
MAX(IF(p.c_name=语文,p.s_score,NULL))为语文,
MAX(IF(p.c_name=英语,p.s_score,NULL))为英语
来自(
选择s . s . id,s . s . name,c . c . name,sc分数
来自学生s
供应链标识=供应链标识的左连接分数南卡罗来纳州
在c.c_id=sc.c_id)p上向左加入航向c
按公共服务标识分组;
2)那么就有人问了,如果我有100门课程不是要写100次名称,这也太麻烦了?接下来请看动态结构化查询语言
我们的动态结构化查询语言是拼接实现的,主要就是拼接我们的课程成绩那一句,所以要先看一下串联函数拼接课程语句
从课程c中选择c_name,CONCAT( MAX(IF(p.c_name=,c_name, ,c.s_score,NULL)) AS ,c _ name;
是的,结果就是上面要的马克斯(男子名等于马克西米利安)函数
然后我么可以用GROUP_CONCAT()函数把这些内容拼接成一句
从课程c中选择GROUP_CONCAT(DISTINCT c_name,CONCAT( MAX(IF(p.c_name=,c_name, ,c.s_score,NULL)) AS ,c _ name);
接下来,拼接结构化查询语言实现需求
- 1.定义一个结构化查询语言变量
SET @ sql=NULL
- 2.把我们的查询课程的结构化查询语言赋给变量
SELECT GROUP _ CONCAT(DISTINCT CONCAT( MAX(IF(p . c_name=,c _ name, ,p.s_score,NULL)) AS ,c_name)) INTO @sql
来自当然;
- 3.拼接结构化查询语言
SET @sql=CONCAT(SELECT p.s_id,p.s_name,,@sql,
从(选择s . s . id,s . s . name,c . c . name,sc分数
来自学生s
供应链标识=供应链标识的左连接分数南卡罗来纳州
在c.c_id=sc.c_id)p上向左加入航向c
GROUP BY p . s _ id );
-预处理语句
从@sql准备stmt
-执行
执行stmt
-销毁
解除分配准备stmt
3)这样每次都写一长串sql也很麻烦?好的那么我们来封装成存储过程
- 1、创建无参存储过程
分隔符$$
创建过程getStudentRow()
开始
-把要执行的结构化查询语言放在这里就可以了
SET @ sql=NULL
挑选
GROUP _ CONCAT(DISTINCT CONCAT( MAX(IF(p . c_name=,c_name, ,p.s_score,NULL)) AS ,c _ name))
从课程到@ sql
SET @sql=CONCAT(SELECT p.s_id,p.s_name,,@sql,
从(选择s . s . id,s . s . name,c . c . name,sc分数
来自学生s
供应链标识=供应链标识的左连接分数南卡罗来纳州
在c.c_id=sc.c_id)p上向左加入航向c
GROUP BY p . s _ id );
从@sql准备stmt
执行stmt
解除分配准备stmt
-把要执行的结构化查询语言放在这里就可以了
结束$ $
分隔符;
-查询存储过程
显示程序状态;
-调用
调用getStudentRow();
这样每次直接调用就可以了?
总结
到此这篇关于关系型数据库如何列转行的文章就介绍到这了,更多相关关系型数据库列转行内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!