如何使用MySQL切割函数实现将一行切割为多行的实际应用

需求背景
用户输入一串标题或者一串诉求内容,通过检索用户输入的内容,判断是否属于某标签下的诉求内容,通过这些标签来对用户的诉求内容进行分派。
1.数据处理阶段:
只需要将满足内容的标签数据查询出来即可;
哪些标签数据在用户输入的内容中都存在,则返回;
标签内容如下展示:在这里插入图片描述
其中 contain_content 字段,就是存储的标签,目的是需要判断标签中逗号分割的内容在用户输入的内容中都存在(少一个都不行)。

实现思路:
将 contain_content 根据逗号进行分割,分割成多行的数据;然后将分割后的数据与输入的内容进行匹配即可。
想法虽好,可是实行起来难啊。
难点1:mysql 切割后的数据如何展示为多行?mysql似乎没有这个函数
难点2:切割后的数据如何对输入的内容进行完全匹配,即切割后的多行值在输入内容中都存在。

第一步:
分割字符串,原数据长这样
在这里插入图片描述

目标数据:
在这里插入图片描述
这里需要运用到mysql字符串切割函数substring_index。
这里先奉上切割后的完整代码

SELECT
	  a.id
     ,substring_index(substring_index(a.contain_content, ',', b.help_temp_id), ',', - 1) AS content
FROM 
(
-- 需求需要一条优先级最高的数据,查询出来的数据如上图
	select 
		*
	from 
		wo_complaint_auto_assign_config
	order by 
		priority_level
	DESC
	LIMIT 1
)  a
INNER JOIN 
	help_temp b
  ON b.help_temp_id <= (length(a.contain_content) - length(REPLACE(a.contain_content, ',', ''))+1)

有时间研究的话,往下看
help_temp 是一个自增序列的表,列是1-1000的id值,可以随着需求不断增加
第一层切割:

substring_index(a.contain_content, ',', b.help_temp_id)

随着help_temp_id增加,截取的字符串依次增。
“a”、“a,b”、“a,b,c”

第二层切割:

substring_index(str, ',' , -1)

获取第一层切割的字符串,按分隔符分割之后的最后一个字符串

substring_index(substring_index(a.contain_content, ',', b.help_temp_id), ',', - 1)

这个最后输出的结果:

"a" "b" "c"

第三步:
与 help_temp 表关联
判断:

length(a.contain_content) - length(REPLACE(a.contain_content, ',', ''))+1

这个存在是将数据分割成多少份?

原始长度 - 去掉分隔符“,”之后的长度 = 分隔符数量
分隔符数量 + 1 = 被分割的数量

这样第一阶段字符串的分割就完成了

第二阶段:
判断用户输入的内容是否都包含切割后的数据。

SELECT 
	COUNT(*) AS total_count
	,SUM(IF(LOCATE(values_column, target_string) > 0, 1, 0)) AS matching_count
FROM 
	your_table;

在切割完成后的数据中统计。
如果 total_count 等于 matching_count,则说明所有的值都存在于目标字符串中。
如果 total_count 小于 matching_count,则说明有些值不在目标字符串中。

实现代码如下:
用户输入的标题和内容,分别用参数 titile 和 common 标识,只要有其中一个参数全包含就返回;

	select 
		distinct
		id
	from 
		temp_table
	where 
	-- ======判断切割完成的列值是否都存在于,需要检查的字符串中,=======
	-- 如果 total 等于 contain,则说明所有的值都存在于目标字符串中。
	-- 如果 total 小于 contain,则说明有些值不在目标字符串中。
		(SELECT COUNT(1) as total FROM temp_table)  = (select SUM(IF(LOCATE(content, title) > 0, 1, 0)) as contain from temp_table)
		or 
		(SELECT COUNT(1) as total FROM temp_table)  = (select SUM(IF(LOCATE(content, common) > 0, 1, 0)) as contain from temp_table)

这样就获取到满足条件的id,通过这个id再去关联获取满足条件的数据即可

最后奉上完整代码

-- 建表DDL
CREATE TABLE `wo_complaint_auto_assign_config` (
  `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'ID',
  `contain_content` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '包含内容',
  `priority_level` int DEFAULT NULL COMMENT '优先级',
  `create_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
)

-- 插入数据
INSERT INTO `wo_complaint_auto_assign_config` (`id`, `contain_content`, `priority_level`, `create_by`, `create_time`, `update_by`, `update_time`) VALUES ('1693931782696927233', 'ETC,呼和浩特', 1, 'admin', '2023-08-22 18:23:03', 'admin', '2023-08-23 09:26:29');


-- ==========================以上是数据提供,可不用提供数据====================================



-- 创建一个自增序列 暂定为1000
with help_temp as 
(
	SELECT
    ones.n + tens.n * 10 + hundreds.n * 100 + thousands.n * 1000 + 1 AS help_temp_id
FROM
    (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL
     SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) ones
CROSS JOIN
    (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL
     SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) tens
CROSS JOIN
    (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL
     SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) hundreds
CROSS JOIN
    (SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL
     SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) thousands
WHERE
    ones.n + tens.n * 10 + hundreds.n * 100 + thousands.n * 1000 < 1000
), 

-- =============================一列切割为多行==================================
temp_table as 
(
SELECT
	  a.id
     ,substring_index(substring_index(a.contain_content, ',', b.help_temp_id), ',', - 1) AS content
FROM 
(
	select 
		*
	from 
		wo_complaint_auto_assign_config
	order by 
		priority_level
	DESC
	LIMIT 1
)  a
INNER JOIN 
	help_temp b
  ON b.help_temp_id <= (length(a.contain_content) - length(REPLACE(a.contain_content, ',', ''))+1)
)


	
select 
	T1.id
	,T2.contain_content 
	,T2.user_id 
	,T2.depart_id 
	,T2.priority_level
from 
(
	select 
		distinct
		id
	from 
		temp_table
	where 
	-- ======判断切割完成的列值是否都存在于,需要检查的字符串中,=======
	-- 如果 total 等于 contain,则说明所有的值都存在于目标字符串中。
	-- 如果 total 小于 contain,则说明有些值不在目标字符串中。
		(SELECT COUNT(1) as total FROM temp_table)  = (select SUM(IF(LOCATE(content, 'ETC呼和浩') > 0, 1, 0)) as contain from temp_table)
		or 
		(SELECT COUNT(1) as total FROM temp_table)  = (select SUM(IF(LOCATE(content, 'ETC呼和浩特') > 0, 1, 0)) as contain from temp_table)
)  T1
 join 
	wo_complaint_auto_assign_config  T2
ON T1.id = T2.id


	

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MySQL提供了一个函数split_string(),它可以将一行数据拆分多行数据,语法如下:split_string(string, delimiter, number_of_elements),其中string参数是需要拆分的字符串,delimiter参数是分隔符,number_of_elements参数是拆分后的元素个数。 ### 回答2: 在MySQL中,可以使用UNION操作符将一行数据拆分多行数据。 假设有一个表格名为"table1",其中有一行数据包含了多个字段,如下所示: 字段1 | 字段2 | 字段3 ------------------------ 1 | A | X,Y,Z 如果我们想要将字段3拆分多行数据,可以使用UNION操作符,如下所示: SELECT 字段1, 字段2, 'X' as 字段3 FROM table1 UNION ALL SELECT 字段1, 字段2, 'Y' as 字段3 FROM table1 UNION ALL SELECT 字段1, 字段2, 'Z' as 字段3 FROM table1 通过以上查询语句,我们将原先的一行数据拆分为了三行数据,每一行的字段3的值分别为X、Y、Z。使用UNION ALL关键字可以保留重复的值,如果不希望包含重复的值可以使用UNION关键字。 使用UNION操作符可以将一行数据拆分多行数据,便于对每个字段进行单独的处理和分析。 ### 回答3: 在MySQL中,可以使用UNION语句将一行数据拆分多行数据。 假设有一张名为students的表,包含以下字段:id, name, subjects。其中subjects字段存储了学生所选的多门课程,以逗号分隔开。 要将每个学生的课程拆分多行数据,可以使用UNION语句。具体步骤如下: 1. 创建一个临时表temp,包含两个字段:id和subject。 2. 使用INSERT INTO语句将原表students中的数据拆分并插入到临时表temp中。可以使用子查询和字符串函数实现,例如: INSERT INTO temp (id, subject) SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(subjects, ',', numbers.n), ',', -1) FROM students, (SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) numbers WHERE CHAR_LENGTH(subjects) - CHAR_LENGTH(REPLACE(subjects, ',', '')) >= numbers.n - 1; 这段代码中,通过子查询生一个数字序列,用来表示需要拆分多行的数量。然后通过SUBSTRING_INDEX和CHAR_LENGTH函数将subjects字段按照逗号进行拆分。 3. 最后,从临时表temp中查询数据即可得到拆分后的多行数据。 例如,查询学号为1的学生的课程拆分后的数据: SELECT * FROM temp WHERE id = 1; 这样就可以将原本存储在一行数据拆分多行数据,以方便后续的查询和处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值