打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
MYSQL-SQL 行转列,列转行(case when)
userphoto

2022.11.01 湖南

关注

SQL行列转换

embelfe_segge

于 2022-07-29 21:48:35 发布

4501

 收藏 9

分类专栏: 面试 学习路线 阿里巴巴 文章标签: android 前端 后端

版权

华为云开发者联盟

该内容已被华为云开发者联盟社区收录

加入社区

面试

同时被 3 个专栏收录

139 篇文章3 订阅

订阅专栏

学习路线

117 篇文章0 订阅

订阅专栏

阿里巴巴

124 篇文章1 订阅

订阅专栏

常见的行列转换包括以下四种情况:

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;


结果展示:

  

涉及知识点:CASE表达式 | 聚合函数

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 '分隔符'])

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表 (学生成绩表)

  

**问题:**实现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);


部分结果展示:

  

涉及知识点: SUBSTRING函数 | SUBSTRING_INDEX函数

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担

————————————————

版权声明:本文为CSDN博主「embelfe_segge」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/embelfe_segge/article/details/126064586

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
oracle 经典分数排名
MySQL经典练习题及答案,常用SQL语句练习50题
中国省市数据库表——MYSql版
ON DUPLICATE KEY UPDATE,唯一索引或者主键插入重复修改记录
如何实现在分组的情况下,以另一个时间字段查询出结果?
SQL servel 查询练习及答案
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服