MySQL 字段根据逗号分割实现列转行substring_index,然后进行group by分组统计

MySQL 统计每个合同类型出现的次数(多选字段)

问题:

有一个合同表,其中合同类型是多选,在数据库中以逗号分隔进行储存,现在要统计每个合同类型出现的次数。

合同表数据:
在这里插入图片描述

实现

第一步:将合同类型按照逗号分隔成多条数据。

期望结果:
在这里插入图片描述
sql实现:

	select
		a.id,
		a.cont_type,
		b.help_topic_id + 1,
		substring_index(substring_index(a.cont_type, ',', b.help_topic_id + 1), ',',-1) type_new
	from opt_cont a
	left join mysql.help_topic b on b.help_topic_id < (length(a.cont_type) - length(replace(a.cont_type, ',', ''))+ 1)

第二步:将新拆分的合同类型分组统计数量。

期望结果:
在这里插入图片描述
sql实现:

select
	t.type_new dictValue,
	count(t.id) dictValueCount
from
	(
	select
		a.id,
		a.cont_type,
		b.help_topic_id + 1,
		substring_index(substring_index(a.cont_type, ',', b.help_topic_id + 1), ',',-1) type_new
	from opt_cont a
	left join mysql.help_topic b on b.help_topic_id < (length(a.cont_type) - length(replace(a.cont_type, ',', ''))+ 1)
	) t
group by t.type_new 

使用到的函数:

1、SUBSTRING_INDEX(str,delim,count):

str:要处理的字符串
delim:分隔符
count:计数
正数:从左往右数,第N个分隔符的左边的全部内容,
负数,那么就是从右边开始数,第N个分隔符右边的所有内容

2、help_topic这张表是mysql自带的连续数列的表

mysql.help_topic这张表我们只用到了它的help_topic_id,
可以看到这个help_topic_id是从0开始一直连续的,
join这张表只是为了确定数据行数。
现在假设我的mysql.help_topic一共只有5条数据,那么最多可转成5行数据,若果现在字段的名字有6个就不能用mysql.help_topic这张表了。

3、substring_index(substring_index(a.execute_name,‘,’,b.help_topic_id+1),‘,’,-1)

select 
a.id,
b.help_topic_id +1,
a.execute_name,
#从左往右循环取 b.help_topic_id+1 个字符
substring_index(a.execute_name,',',b.help_topic_id+1), 
#从右往左第一个,右边的数据
substring_index(substring_index(a.execute_name,',',b.help_topic_id+1),',',-1) 
from `user` a
left join mysql.help_topic b
on b.help_topic_id < (length(a.execute_name) - length(replace(a.execute_name,',',''))+1)
order by a.id, b.help_topic_id

4、on条件后面的b.help_topic_id < (length(a.execute_name) - length(replace(a.execute_name,‘,’,‘’))+1)

得到被逗号分隔的字段一共有几个(既计算出原始的字段长度,和去掉逗号的字段长度,两者的差就是有几个逗号,三个逗号就表示有四个字段…)

5、join 这个join最基本原理是笛卡尔积。通过这个方式来实现循环

这种方法的缺点在于,我们需要一个拥有连续数列的独立表(这里是incre_table)。并且连续数列的最大值一定要大于符合分割的值的个数。
例如有一行的mSize 有100个逗号分割的值,那么我们的incre_table 就需要有至少100个连续行。
mysql内部也有现成的连续数列表可用。如mysql.help_topic:一般能满足于大部分需求了。

猜你喜欢

转载自blog.csdn.net/qq_42547733/article/details/134117136