当前位置:网站首页>SQL行列转换
SQL行列转换
2022-07-31 04:47:00 【jiey0407】
常见的行列转换包括以下四种情况:
1.列转行
2.行转列
3.列转换成字符串
4.字符串转换成列
1.列转行
导入数据
DROP TABLE IF EXISTS `t_student`;
CREATE TABLE `t_student` (
`id` int(20) NOT NULL AUTO_INCREMENT COMMENT '主键 id',
`name` varchar(50) DEFAULT NULL COMMENT '姓名',
`course` varchar(50) DEFAULT NULL COMMENT '课程',
`score` int(3) DEFAULT NULL COMMENT '成绩',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
INSERT INTO `t_student` VALUES (1,'张三', '语文', 95);
INSERT INTO `t_student` VALUES (2,'李四', '语文', 99);
INSERT INTO `t_student` VALUES (3,'王五', '语文', 80);
INSERT INTO `t_student` VALUES (4,'张三', '数学', 86);
INSERT INTO `t_student` VALUES (5,'李四', '数学', 96);
INSERT INTO `t_student` VALUES (6,'王五', '数学', 81);
INSERT INTO `t_student` VALUES (7,'张三', '英语', 78);
INSERT INTO `t_student` VALUES (8,'李四', '英语', 88);
INSERT INTO `t_student` VALUES (9,'王五', '英语', 87);
INSERT INTO `t_student` VALUES (10,'张三', '历史', 98);
INSERT INTO `t_student` VALUES (11,'李四', '历史', 85);
INSERT INTO `t_student` VALUES (12,'王五', '历史', 89);
t_student表 (学生成绩表)

1.1MAX(CASE WEHN)方法
SELECT name as '姓名',
MAX(CASE WHEN course = '语文' THEN score END) AS '语文',
MAX(CASE WHEN course = '数学' THEN score END) AS '数学',
MAX(CASE WHEN course = '英语' THEN score END) AS '英语',
MAX(CASE WHEN course = '历史' THEN score END) AS '历史'
FROM t_student
GROUP BY name;
结果展示:

1.2 SUM(IF(条件,列值,0))
SELECT name as '姓名',
SUM(IF(course = '语文',score,0)) AS '语文',
SUM(IF(course = '数学',score,0)) AS '数学',
SUM(IF(course = '英语',score,0)) AS '英语',
SUM(IF(course = '历史',score,0)) AS '历史'
FROM t_student
GROUP BY name;
结果展示:

涉及知识点:IF函数
2.行转列
导入数据
DROP TABLE IF EXISTS `t_course`;
CREATE TABLE `t_course` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(50) DEFAULT NULL COMMENT '用户名',
`chinese` double DEFAULT NULL COMMENT '语文成绩',
`math` double DEFAULT NULL COMMENT '数学成绩',
`english` double DEFAULT NULL COMMENT '英语成绩',
`history` double DEFAULT NULL COMMENT '历史成绩',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO t_course VALUES ('1', '张三', '95', '86', '78', '98');
INSERT INTO t_course VALUES ('2', '李四', '99', '96', '88', '85');
INSERT INTO t_course VALUES ('3', '王五', '80', '81', '87', '89');
t_course表

行转列的过程, 其实就是列转行的逆过程
-- 列转行:通过UNION或UNION ALL实现
SELECT user_name,'语文' AS course,chinese AS score FROM t_course
UNION ALL
SELECT user_name,'数学' AS course,math AS score FROM t_course
UNION ALL
SELECT user_name,'英语' AS course,english AS score FROM t_course
UNION ALL
SELECT user_name,'政治' AS course,history AS score FROM t_course
ORDER BY user_name;
部分结果展示:

涉及知识点: 组合查询
UNION 与 UNION ALL的区别:
1.对重复结果的处理: UNION会去掉重复记录,UNION ALL不会
2.对排序的处理: UNION会排序,UNION ALL只是简单地将两个结果集合并
3.效率方面的区别: 因为UNION会做去重和排序处理,因此效率比UNION ALL慢很多
3.列转换成字符串
在某些场景下,我们可能会对单列或者多列转换成字符串,实现这个需求需要使用到 GROUP_CONCAT函数
语法格式
GROUP_CONCAT([DISTINCT] 要连接的字段 [ORDER BY 排序字段 ASC/DESC] [SEPARATOR '分隔符'])
导入数据
DROP TABLE IF EXISTS `t_student`;
CREATE TABLE `t_student` (
`id` int(20) NOT NULL AUTO_INCREMENT COMMENT '主键 id',
`name` varchar(50) DEFAULT NULL COMMENT '姓名',
`course` varchar(50) DEFAULT NULL COMMENT '课程',
`score` int(3) DEFAULT NULL COMMENT '成绩',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
INSERT INTO `t_student` VALUES (1,'张三', '语文', 95);
INSERT INTO `t_student` VALUES (2,'李四', '语文', 99);
INSERT INTO `t_student` VALUES (3,'王五', '语文', 80);
INSERT INTO `t_student` VALUES (4,'张三', '数学', 86);
INSERT INTO `t_student` VALUES (5,'李四', '数学', 96);
INSERT INTO `t_student` VALUES (6,'王五', '数学', 81);
INSERT INTO `t_student` VALUES (7,'张三', '英语', 78);
INSERT INTO `t_student` VALUES (8,'李四', '英语', 88);
INSERT INTO `t_student` VALUES (9,'王五', '英语', 87);
INSERT INTO `t_student` VALUES (10,'张三', '历史', 98);
INSERT INTO `t_student` VALUES (11,'李四', '历史', 85);
INSERT INTO `t_student` VALUES (12,'王五', '历史', 89);
t_student表 (学生成绩表)

**问题:**实现t_student表中课程和成绩拼接为一个字符串的功能
SELECT name, GROUP_CONCAT(course, ":", score) AS '课程:成绩'
FROM t_student
GROUP BY name;
结果展示:

涉及知识点:GROUP_CONCAT函数
4.字符串转换成列
在某些场景下,我们需要把某一列的字符串转成多列
导入数据
t_user_order表 (用户订单表)
DROP TABLE IF EXISTS `t_user_order`;
CREATE TABLE `t_user_order` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键 id',
`user_id` varchar(50) DEFAULT NULL COMMENT '用户 id',
`order_id` varchar(100) DEFAULT NULL COMMENT '订单 ids',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO t_user_order VALUES ('1', 'user1', '1,3,5,19,20');
INSERT INTO t_user_order VALUES ('2', 'user2', '2,4,6,8,30,50');
INSERT INTO t_user_order VALUES ('3', 'user3', '11,15,29,31,33');
结果展示:

从上表可以看出用户ID (user_id)和订单ID (order_id)之间的关系是一对多关系,用户ID对应的订单 ID是一个字符串
问题: 将order_id中的字符串转换成列
思路: 利用help_topic表把以逗号分隔的字符串转换成行
-- 字符串转换成列: 利用SUBSTRING_INDEX和mysql.help_topic实现
SELECT a.user_id,
SUBSTRING_INDEX(SUBSTRING_INDEX(a.order_id, ',', b.help_topic_id + 1 ), ',',- 1 )AS order_id
FROM t_user_order AS a
LEFT JOIN mysql.help_topic AS b
ON b.help_topic_id < (length(a.order_id) - length(REPLACE(a.order_id, ',', '' )) + 1);
部分结果展示:

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦
边栏推荐
- Go language study notes - dealing with timeout problems - Context usage | Go language from scratch
- Minesweeper game - C language
- MySQL模糊查询可以使用INSTR替代LIKE
- MySQL数据库安装配置保姆级教程(以8.0.29为例)有手就行
- Open Source Database Innovation in the Digital Economy Era | 2022 Open Atom Global Open Source Summit Database Sub-Forum Successfully Held
- 问题7:列表的拼接
- 两个地址池r2负责管地址池r1负责管dhcp中继
- HCIP第十天_BGP路由汇总实验
- 【C语言】操作符详解
- Unity框架设计系列:Unity 如何设计网络框架
猜你喜欢

Win10 CUDA CUDNN installation configuration (torch paddlepaddle)

MySQL based operations

Unity资源管理系列:Unity 框架如何做好资源管理

The input input box displays the precision of two decimal places

mysql基础知识(二)

The Vue project connects to the MySQL database through node and implements addition, deletion, modification and query operations

MATLAB/Simulink&&STM32CubeMX工具链完成基于模型的设计开发(MBD)(三)

idea工程明明有依赖但是文件就是显示没有,Cannot resolve symbol ‘XXX‘

【云原生】DevOps(五):集成Harbor

Two address pools r2 are responsible for managing the address pool r1 is responsible for managing dhcp relays
随机推荐
30 Years of Open Source Community | 2022 Open Atom Global Open Source Summit 30 Years of Open Source Community Special Event Held Successfully
Unity Tutorial: URP Rendering Pipeline Practical Tutorial Series [1]
ENSP, VLAN division, static routing, comprehensive configuration of Layer 3 switches
三子棋的代码实现
three.js 制作3D相册
el-image标签绑定点击事件后没有有用
Win10 CUDA CUDNN installation configuration (torch paddlepaddle)
Gaussian distribution and its maximum likelihood estimation
MySQL基础操作
【C语言】操作符详解
【云原生】DevOps(五):集成Harbor
三道leetcode上的oj题
强化学习:从入门到入坑再到拉屎
MySQL修改root账号密码
MySQL模糊查询可以使用INSTR替代LIKE
【py脚本】批量二值化处理图像
mysql数据库安装(详细)
C# 实现PLC的定时器
Minio上传文件ssl证书不受信任
three.js make 3D photo album