mysql使用逗号分隔的一行数据转多行数据

news2024/12/24 9:07:04

文章目录

  • 学习链接
  • 准备
    • 建表
    • 插入数据
  • 方法
    • MySQL逗号拼接的列拆分为多行(不使用mysql.help_topic)
    • 遇到字段以逗号分隔符分号分隔符存放多个值,需要一行转化多行,以用来关联(使用mysql.help_topic)
      • 改为LEFT JOIN后的效果
      • 封装为函数
      • 原理简析
      • SUBSTRING_INDEX(str, delim, count)
      • replace( str, from_str, to_str)
      • LENGTH( str )
    • 将逗号分割的字段内容转换为多行并group by
      • 1、原来的字段格式
      • 2、将逗号分割的字段内容转换为多行
      • 3、对以上结果进行分组

学习链接

MYSQL: sql中某一个字段内容为用逗号分割的字符串转换成多条数据(适用于部分树机构)

MySQL逗号拼接的列拆分为多行(不使用mysql.help_topic)

遇到字段以逗号分隔符分号分隔符存放多个值,需要一行转化多行,以用来关联(使用mysql.help_topic)

【mysql】将逗号分割的字段内容转换为多行并group by

Mysql 行转列,把逗号分隔的字段拆分成多行(这个也还可以)

【mysql】将逗号分割的字段内容转换为多行并group by(这个讲的很详细)

MySql字符串拆分实现split功能(字段分割转列、转行)(很nice)

MySql逗号拼接的列拆分为多行(nice)

PostgreSQL 字符串分隔函数(regexp_split_to_table)介绍以及示例应用

准备

建表

CREATE TABLE `u_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `hobbies` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

插入数据

INSERT INTO `test`.`u_user` (`id`, `name`, `hobbies`) VALUES (1, 'zj', 'ps,blender,java');
INSERT INTO `test`.`u_user` (`id`, `name`, `hobbies`) VALUES (2, 'ls', 'u8,u9,pmp,cpa');
INSERT INTO `test`.`u_user` (`id`, `name`, `hobbies`) VALUES (3, 'zzhua', 'spring');
INSERT INTO `test`.`u_user` (`id`, `name`, `hobbies`) VALUES (4, 'zengjian', NULL);
INSERT INTO `test`.`u_user` (`id`, `name`, `hobbies`) VALUES (5, 'halo', '');
INSERT INTO `test`.`u_user` (`id`, `name`, `hobbies`) VALUES (6, 'netty', 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z');

-- truncate table u_user;

插入数据如下图所示,有多个的使用逗号分隔的,有单个未使用逗号的,有nul的,有空字符的,有特别多个的。
在这里插入图片描述

方法

MySQL逗号拼接的列拆分为多行(不使用mysql.help_topic)

SELECT
	id,
	name,
	SUBSTRING_INDEX( SUBSTRING_INDEX( hobbies, ',', n ), ',', - 1 ) AS split 
FROM
	`u_user`,
	( SELECT @rownum := @rownum + 1 AS n FROM ( SELECT @rownum := 0 ) r, `u_user` ) x 
WHERE
	1 = 1 
	AND n <= ( LENGTH( hobbies ) - LENGTH( REPLACE ( hobbies, ',', '' ) ) + 1 ) 
ORDER BY
	id

在这里插入图片描述
从查询结果来看,这个方法有几个缺点:1、不按顺序来(如果顺序没有特定含义的话,可以忽略),2、会忽略null的数据 3、netty所在的那1条数据,只拆分出了前面6个(这个问题比较严重,这个6经过测试是原表数据的总条数。假设原表中只有2条数据,那么netty所在的那条数据就只会拆分出前2条数据)

遇到字段以逗号分隔符分号分隔符存放多个值,需要一行转化多行,以用来关联(使用mysql.help_topic)

原文链接:https://blog.csdn.net/qq_35124072/article/details/124716478

SELECT
	u.id, 
	u.name, 
	SUBSTRING_INDEX( SUBSTRING_INDEX( u.`hobbies`, ',', b.help_topic_id + 1 ), ',', -1 ) AS REGEXP_COUNT_COL 
FROM
	u_user u
	INNER JOIN mysql.help_topic b ON b.help_topic_id < (
		LENGTH( u.`hobbies` ) - LENGTH( REPLACE(u.`hobbies`,',','') )  +  1  -- hobbies的长度 - hobbies去掉所有逗号的长度 + 1
	)

在这里插入图片描述
从查询结果来看,1、保留了原来的顺序,2、忽略了null的数据(可以将INNER JOIN改成LEFT JOIN即可),3、netty那一条比较多的数据保留了下来,4、感觉就是上一种方法的变体,就是借助了mysql.topic表的从0开始递增的id字段,这个表中在当前5.17.7版本中有637条数据。5、其实可以不用借助mysql.topic这张表,但是我们就需要自建这样的一张表了,或者我们手动select 1 union select 2 union…这样拼着来使用

改为LEFT JOIN后的效果

在这里插入图片描述

封装为函数

可以参照上面将待分隔的数据作为参数传入,并可封装为函数使用,如下:
在这里插入图片描述

原理简析

1、mysql.help_topic表的help_topic_id 字段是从0开始的自增的int类型的值,所以当部分用户访问该表被拒绝的时候,可以自己建一张临时辅助表,id的值建议至少从0到100,保存100列(取决于参数中可能出现多少个分隔符);
2、如果是别的分隔符,把sql中的’;'替换成其他就好
3、sql原理:大概就是利用参数中分隔符出现的次数来重复连接,以多次返回值,每次返回值都利用SUBSTRING_INDEX截取不同位置的值,达到拆分到多行的目的。

SUBSTRING_INDEX(str, delim, count)

  • str 需要拆分的字符串
  • delim 分隔符,通过某字符进行拆分
  • count 当 count 为正数,取第 n 个分隔符之前的所有字符; 当 count 为负数,取倒数第 n 个分隔符之后的所有字符
-- 得到的结果: 7654,7698
SUBSTRING_INDEX('7654,7698,7782,7788',',',2) 

-- 得到的结果: 7782,7788
SUBSTRING_INDEX('7654,7698,7782,7788',',',-2)

replace( str, from_str, to_str)

  • str 需要进行替换的字符串
  • from_str 需要被替换的字符串
  • to_str 需要替换的字符串
-- 得到的结果: 7654769877827788
REPLACE('7654,7698,7782,7788',',','')

LENGTH( str )

  • str 需要计算长度的字符串
-- 得到的结果: 19
LENGTH('7654,7698,7782,7788')

将逗号分割的字段内容转换为多行并group by

1、原来的字段格式

在这里插入图片描述

2、将逗号分割的字段内容转换为多行

下面直接给出sql,并对sql的每一步做出解释,更有助于大家理解

首先要说明的是,mysql.help_topic本身是mysql的一张信息表,用来存储各种注释等帮助信息,help_topic拥有一个自增为1的id属性–help_topic_id ,并且可以当做下标来使用,拥有固定数量的数据
解释:

  1. length(a.attendee_uid) - length(REPLACE(a.attendee_uid, ‘,’, ‘’)) + 1
  2. 第一步的意思是 字段attendee_uid的长度 - 字段attendee_uid去除掉逗号的长度,然后再+1就得到了通过逗号分割后有几条数据
  3. 比如上一步得到是3 那就可以确定这个字段要拆分为3行 help_topic_id<3 也就是可以得到下标 0,1,2
  4. 比如这条数据’zhangsan,lisi,wangwu’ 第一个substring_index的意思就是把’zhangsan,lisi,wangwu’通过逗号分割,然后取b.help_topic_id + 1(help_topic_id就是第3步得到的下标)结果就是zhangsan
  5. 第二个substring_index的意思是 再从第4步的结果 从右边取第一个, 因为’zhangsan,lisi,wangwu’如果获取到下标为2的话那得到的就是’zhangsan,lisi’ 所以再从右边取第一个就得到了 ‘lisi’
SELECT 
	a.id '会议id', 
	a.attendee_uid '原始参会人列表', 
	# 4、比如这条数据'zhangsan,lisi,wangwu'  第一个substring_index的意思就是把'zhangsan,lisi,wangwu'通过逗号分割,
	#    然后取b.help_topic_id + 1(help_topic_id就是第3步得到的下标)结果就是zhangsan
	# 5 第二个substring_index的意思是 再从第4步的结果 从右边取第一个, 因为'zhangsan,lisi,wangwu'如果获取到下标为2的话那得到的就是'zhangsan,lisi'  所以再从右边取第一个就得到了 'lisi'
	substring_index(substring_index(a.attendee_uid, ',', b.help_topic_id + 1), ',', -1) AS '分割后的参会人账号' 
FROM `fusion_meeting` a 
JOIN mysql.help_topic b 
# 1、length(a.attendee_uid) - length(REPLACE(a.attendee_uid, ',', '')) + 1 
# 2、这个的意思是 字段attendee_uid的长度 - 字段attendee_uid去除掉逗号的长度,然后再+1就得到了通过逗号分割后有几条数据
# 3、比如上一步得到是3  那就可以确定这个字段要拆分为3行 help_topic_id<3 也就是可以得到下标 0,1,2
ON b.help_topic_id < length(a.attendee_uid) - length(REPLACE(a.attendee_uid, ',', '')) + 1
WHERE a.hw_conf_id = '969471016';

结果:
在这里插入图片描述

3、对以上结果进行分组

SELECT uid as '参会人账号',COUNT(*) '参会次数' FROM (
	SELECT 
		a.id '会议id', 
		a.attendee_uid '原始参会人列表', 
		substring_index(substring_index(a.attendee_uid, ',', b.help_topic_id + 1), ',', -1) AS uid 
	FROM `fusion_meeting` a 
	JOIN mysql.help_topic b 
		 ON b.help_topic_id < length(a.attendee_uid) - length(REPLACE(a.attendee_uid, ',', '')) + 1
	WHERE a.hw_conf_id = '969471016'

) c GROUP BY c.uid;

结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1605824.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DevOps是什么?

DevOps是一系列实践、工具和文化理念的组合&#xff0c;旨在自动化并整合软件开发和信息技术运维团队之间的流程。以下是DevOps的几个关键点&#xff1a; 沟通与协作&#xff1a;DevOps强调开发和运维团队之间的沟通与合作&#xff0c;通过改善这两个部门间的协作关系&#xff…

OpenHarmony轻量系统开发【13】鸿蒙小车开发

13.1 小车介绍 基于鸿蒙系统 Hi3861 的WiFi小车 首先&#xff0c;我们得有一套WiFi小车套件&#xff0c;其实也是Hi3861 加上电机、循迹模块、超声波等模块。 小车安装完大概是这样&#xff1a; 13.2 电机驱动 我们这里先只做最简单的&#xff0c;驱动小车的电机&#xff…

奶酪——并查集,BFS,DFS(NOIP2017提高组)

目录 题目 思路 并查集 代码&#xff08;java&#xff09; BFS&#xff08;DFS同理&#xff09; 代码&#xff08;C&#xff09; 题目 思路 这个题目意思是有很多个球分布在一个三维空间内&#xff0c;如果这些球相切或者相交都可以互相到达&#xff0c;我们需要判断能否…

【python从入门到精通】-- 第五战:函数大总结

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文…

元宇宙VR虚拟线上展馆满足企业快速布展的需要

想要拥有一个VR线上虚拟展馆&#xff0c;展现您的城市风采或企业特色吗? 相比实体展馆搭建&#xff0c;VR线上虚拟展馆投入资金少&#xff0c;回报周期短&#xff0c;只需几个月的时间&#xff0c;您就能开始资金回笼。那么一个VR线上虚拟展馆多少钱呢? 深圳VR公司华锐视点基…

C语言如何使⽤指针?

一、问题 指针变量在初始化以后就可以使⽤和参与操作了&#xff0c;那么就要⽤到对指针变量最常⽤的两个操作符——> * 和 &#xff06; 。 二、解答 这⾥⼜要提到始终贯穿着指针的⼀个符号“ * ”&#xff0c;但是这⾥的“ * ”是作为指针运算符使⽤的&#xff0c;叫做取内…

三大常用自动化框架对比

上次发布过性能测试工具的对比后&#xff0c;有小伙伴后台留言&#xff0c;想了解一下自动化测试框架的对比&#xff0c;尤其是RobotFramework、pytest和unitest之间的优劣势情况。 这不我们今天就来分析一下他们之间的区别和各自的优缺点。 1 RobotFramework 优点&#xff1a;…

selenium 下载文件取消安全下载的方法

问题描述 我要从一个网站上下载文件&#xff0c;谷歌浏览器总是自动阻止下载&#xff0c;并询问我是否保留。 可是&#xff0c;我想要的是不要询问&#xff0c;默认下载即可。 运行环境 OS: macOSselenium: 4.19.0python: 3.10.11Chrome: 124.0.6367.62selenium chromedrive…

openEuler-23.03下载

下载地址&#xff1a;openEuler下载 | 欧拉系统ISO镜像 | openEuler社区官网 下载版本&#xff1a;openEuler-23.03-x86_64-dvd.iso

CTF中常见的四种python逆向

说在前面&#xff1a; 什么是pyc文件&#xff1f; pyc是一种二进制文件&#xff0c;是由py文件经过编译后&#xff0c;生成的文件&#xff0c;是一种byte code&#xff0c;py文件变成pyc文件后&#xff0c;加载的速度有所提高&#xff0c; pyc 文件是 Python 编译过的字节码文…

WdatePicker异常,无法弹出日期选择框

官网&#xff1a;My97日期控件官方网站 My97 DatePickerhttp://www.my97.net/ 可能使版本太老了&#xff0c;可以更新一下&#xff0c;然后根据官方的文件进行使用。 我的异常是因为在网上找的包里面缺少文件&#xff0c;去官网拉了一下最新的就行了。

【Linux驱动层】iTOP-RK3568学习之路(二):vscode中设置头文件路径-完成代码自动补全

在Ubuntu下用vscode写Linux驱动层的时候&#xff0c;需要添加头文件&#xff1a; #include<linux/module.h> #include<linux/init.h> #include<linux/kernel.h>但vscode没有智能提示&#xff0c;因此需要我们手动添加自己的头文件路径&#xff1a; topeetu…

Ubuntu 23.10.1 nginx源码安装

注&#xff1a;以下所有命令均在root管理员模式下&#xff0c;若不是&#xff0c;请在所有命令前加sudo 1、安装依赖库 1.1、安装gcc g的依赖库 apt-get install build-essential apt-get install libtool1.2、安装pcre依赖库 apt-get update apt-get install libpcre3 lib…

嵌入式科普(15)小米su7成本分析和拆解之智驶、座舱分析

目录 一、概述 二、小米su7成本分析 2.1 整车成本构成 2.2 三电系统 2.3 车身与底盘 2.3 智能网联 2.4 内外饰 三、小米su7拆解之智驶、座舱分析 3.1 主要芯片 3.2 智能驾驶&智能座舱 四、NXP S32K324汽车通用微控制器 嵌入式科普(15)小米su7成本分析和拆解之智…

【结构型模式】外观模式

​一、外观模式概述 外观模式定义与意图&#xff1a;外观类为复杂的子系统提供了一个统一的入口。外观模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用。&#xff08;对象结构型模式&#xff09; 外观模式的特点&#xff1a; 1.又叫做门面模式&#xf…

JRT在线初始化完善

之前实现的在线初始化留了个尾巴&#xff0c;那就是环境下载页构造zip包的时候没修改JRTBrowser的连接串地址为当前网站&#xff0c;这样就要求网站部署好之后给用户下载之前有人要把服务器的浏览器地址配置好。这样就增加一个运维工作&#xff0c;如果忘了或者不知道的人就会导…

在Windows安装R语言

直接安装R语言软件 下载网址&#xff1a;R: The R Project for Statistical Computing 下载点击install R for the first time 通过Anaconda下载RStudio 提前下载好Anaconda 点击Anaconda Navigate 点击RStudio的Install下载就好了

labelimg安装和使用(解决闪退问题)

&#x1f308;个人主页&#xff1a;Rookie Maker &#x1f525; 系列专栏&#xff1a;计算机视觉 &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于IT的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎来到我的代码世界~ &#x1f601; 喜…

【行为型模式】命令模式

一、命令模式概述 命令模式的定义&#xff1a;将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。(对象行为型) 命令模式优缺点&#xff1a; 优点&#xff1a; 1.类间解耦&#xff1a;调用者角色与接收者角色之间没有任何依…

复合升降机器人教学科研平台——技术方案

一&#xff1a;功能概述 1.1 功能简介 复合升降机器人是一款集成移动底盘、机械臂、末端执行器、边缘计算平台等机构形成的教学科研平台&#xff0c;可实现机器人建图导航、路径规划&#xff0c;机械臂运动学、动力学、轨迹规划、视觉识别等算法功能和应用&#xff0c;提供例如…