当前位置:网站首页>MySql string splitting realizes the split function (field splitting, column switching, row switching)
MySql string splitting realizes the split function (field splitting, column switching, row switching)
2022-07-29 12:32:00 【bluepad】
字符串转多行
需求描述
实现的sql
案例演示
字符串拆分: SUBSTRING_INDEX(str, delim, count)
替换函数:replace( str, from_str, to_str)
获取字符串长度:LENGTH( str )
实现的原理解析
实现sql
正式的原理解析
Step1:首先获取最后需被拆分成多少个字符串,利用 help_topic_id 来模拟遍历 第n个字符串.
Step2:根据“,”逗号来拆分字符串,此处利用 SUBSTRING_INDEX(str, delim, count) 函数,最后把结果赋值给 num 字段.
扩展:判断外部值是否在 num列值中
find_in_set
instr
字符串转多列
需求描述
数据库中 num字段值为:
实现的效果:需要将一行数据变成多行
实现的sql
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1),',',-1) AS num
FROM mysql.help_topic
WHERE help_topic_id < LENGTH('7654,7698,7782,7788')-LENGTH(REPLACE('7654,7698,7782,7788',',',''))+1
案例演示
CREATE TABLE `company` (
`id` int(20) DEFAULT NULL,
`name` varchar(100) DEFAULT NULL,
`shareholder` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `company` VALUES ('1', '阿里巴巴', '马云');
INSERT INTO `company` VALUES ('2', '淘宝', '马云,孙正义');
1、原始数据演示
2、处理结果演示
3、sql语句
SELECT a.id
, a.NAME
, substring_index(substring_index(a.shareholder, ',', b.help_topic_id + 1), ',', - 1) AS shareholder
FROM company a
INNER JOIN mysql.help_topic b
ON b.help_topic_id < (length(a.shareholder) - length(REPLACE(a.shareholder, ',', '')) + 1)
涉及的知识点如下:
字符串拆分: SUBSTRING_INDEX(str, delim, count)
参数解说 解释
str 需要拆分的字符串
delim 分隔符,通过某字符进行拆分
count 当 count 为正数,取第 n 个分隔符之前的所有字符; 当 count 为负数,取倒数第 n 个分隔符之后的所有字符.
举例
(1)获取第2个以逗号为分隔符之前的所有字符.
SELECT SUBSTRING_INDEX('7654,7698,7782,7788',',',2);
(2)获取最后一个到倒数第2个以逗号分隔符之后的所有字符
SELECT SUBSTRING_INDEX('7654,7698,7782,7788',',',-2);
所以,我们的核心代码中的 -1 ,就是获取以逗号为分隔符的最后一个值;也就是7788
替换函数:replace( str, from_str, to_str)
参数名 解释
str 需要进行替换的字符串
from_str 需要被替换的字符串
to_str 需要替换的字符串
举例
将分隔符逗号替换为空.
SELECT REPLACE('7654,7698,7782,7788',',','');
获取字符串长度:LENGTH( str )
参数名 解释
str 需要计算长度的字符串
获取 ‘7654,7698,7782,7788’ 字符串的长度
SELECT LENGTH('7654,7698,7782,7788')
实现的原理解析
【4.1】 实现sql
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1),',',-1) AS num
FROM mysql.help_topic
WHERE help_topic_id < LENGTH('7654,7698,7782,7788')-LENGTH(REPLACE('7654,7698,7782,7788',',',''))+1
此处利用 mysql 库的 help_topic 表的 help_topic_id 来作为变量,因为 help_topic_id 是自增的,当然也可以用其他表的自增字段辅助.
help_topic 表:
注意,这个辅助表的ID最大长度只有658;如果过长的字符串,可能需要借助其他自增的辅助表(可以是现有表,也可以自己造一个 1,2,3,4 递增的行即可)
【4.2】正式的原理解析
原SQL
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1),',',-1) AS num
FROM mysql.help_topic
WHERE help_topic_id < LENGTH('7654,7698,7782,7788')-LENGTH(REPLACE('7654,7698,7782,7788',',',''))+1
Step1:首先获取最后需被拆分成多少个字符串,利用 help_topic_id 来模拟遍历 第n个字符串.
这一步核心就是获取,有多少个分隔符,比如本文的案例,就是知道有多少个逗号
涉及的代码片段:
help_topic_id < LENGTH('7654,7698,7782,7788')-LENGTH(REPLACE('7654,7698,7782,7788',',',''))+1
因为 help_topic_id是从0开始的,所以会得出 help_topic_id 值为:0~3,共4行数据;
Step2:根据“,”逗号来拆分字符串,此处利用 SUBSTRING_INDEX(str, delim, count) 函数,最后把结果赋值给 num 字段.
涉及的代码片段:
SUBSTRING_INDEX(SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1),',',-1) AS num
第一步:
以”,”逗号为分隔符,根据 help_topic_id 的值来截取第n+1个分隔符之前所有的字符串. (此处 n+1 是因为help_topic_id 是从0开始算起,而此处需从第1个分隔符开始获取.)
SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1)
eg:
当 help_topic_id = 0时,获取到的字符串 = 7654
当 help_topic_id = 1时,获取到的字符串 = 7654,7698 …(以此类推)
第二步:
以”,”逗号为分隔符,截取倒数第1个分隔符之后的所有字符串.
SUBSTRING_INDEX(SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1),',',-1)
eg:
根据第一步,当 help_topic_id = 0时,获取到的字符串 = 7654,此时第二步截取的字符串 = 7654
根据第一步,当 help_topic_id = 1时,获取到的字符串 = 7654,7698,此时第二步截取的字符串 = 7698
…(以此类推)
最终成功实现了以下效果 ~
扩展:判断外部值是否在 num列值中
【5.1】find_in_set
如果匹配到了会得出1;如下图
实际业务中,我们只需要 where find_in_set(id,ids)>0
就可以判断出;id列,是否在 ids列中出现过;做表连接的时候,也可以这样;
【5.2】instr
我们可以看出,instr是找出 参数2=》也就是上图中的 ‘123’ 在参数1=》也就是上图中的 ‘321,123,555,12345’ 中最开始出现的位置;
所以我们也只需要 where find_in_set(ids,id)>0 ,就可以判断出 id 在 ids中出现过;
但这有一个问题,如果逗号分隔开的字符串,包含我们查找的字符串,也会显示出来,这就不符合我们 根据分隔符 , 判断 查找字符串id 是否出现在 ids 中;
如下:
我们本来想查以逗号为分隔的完全匹配,但是12345包含了 123 所以查出来的结果也是>0的,这不对;
所以我们为了避免这种情况,可以加上分隔符;然后再用 字符串+分隔符作为 查找的字符串 来 匹配;
我们被查找的字符串 ids 中 再加上一个正常的 123, 再查看,如下图:确实是对的
Some special data,May split the string suffix some of the same,Can cause the error,例如以下:
在字符串中搜索 ‘23’的位置,‘123’The suffix is’23’,Can cause the error
Can add a comma on both sides of the string,To ensure that the string can完全匹配
字符串转多列
SELECT
-- Capture the first comma in front of the data,As the first string
substring_index( ids, ',', 1 ) id1,
-- 在52,15字符串中,From the position of the comma in the string+1Began to capture is the second string
SUBSTR( substring_index( ids, ',', 2 ), LOCATE( ',', substring_index( ids, ',', 2 ), 1 )+ 1 ) id2,
-- The first string and the second string length+2(两个逗号),Starting from this position to intercept is the third string
SUBSTR(
ids,
LENGTH(
CONCAT(
substring_index( ids, ',', 1 ),
SUBSTR( substring_index( ids, ',', 2 ), LOCATE( ',', substring_index( ids, ',', 2 ), 1 ) )))+ 2
) id3
FROM
( SELECT REPLACE ( REPLACE ( '[52,15,894]', '[', '' ), ']', '' ) AS ids ) t
转自:https://blog.csdn.net/pjymyself/article/details/81668157
https://www.cnblogs.com/gered/p/10797012.html#_label1
边栏推荐
- SQL clock 】 【 daily DAY 21 丨 report the state of the system date of continuous difficulty difficult 】 【
- js进阶四(map、reduce、filter、sort、箭头函数、class继承、yield)
- mongo根据时间字段进行时间格式化并进行统计
- 365天挑战LeetCode1000题——Day 043 有效的正方形 数学
- Path dependence - accidental decision to rely on.
- TiDB upgrade share with case (TiDB v4.0.1 to v5.4.1)
- 小程序云函数实现微信支付如此简单
- 国内首秀元宇宙Live House圆满收官,百事可乐虚拟偶像真的好会!!
- 【每日SQL打卡】DAY 26丨餐馆营业额变化增长【难度中等】
- "Qidong well day lily" is the national geographical indications protection products?Ants investigation on July 29, the answer
猜你喜欢
随机推荐
【实用工具】Image Assistant下载指定页面的所有图片
WPF 截图控件之绘制方框与椭圆(四) 「仿微信」
第十章 发现和记录 REST API
The company has a new product, do you want to hire an agent?
金仓数据库KingbaseES客户端编程接口指南-ODBC(8. 示例说明)
记账APP:小哈记账3——登录页面的制作
【每日SQL打卡】DAY 27丨每次访问的交易次数【难度困难-提前放出来】
数组及其内存管理三问
【多线程】——synchronized关键字
金仓数据库KingbaseES客户端编程接口指南-ODBC(9. 疑难解答)
2.2选择排序
MLX90640 infrared thermal imaging temperature measuring sensor module development notes (9)
Network layer and transport layer restrictions
第二章总结
DAY 24 daily SQL clock 】 【 丨 find the beginning and end of the continuum digital difficulty moderate 】 【
XSS漏洞分析
redis数据库基本知识学习——基础、常用
Codeforces Round #797 (Div. 3)个人题解
金仓数据库KingbaseES安全指南--6.8. SSPI身份验证
DAY 25 丨 daily SQL clock 】 【 o team number [difficult medium]