当前位置: 首页 > MySQL数据库

Mysql逗号拼接字符串的关联查询及统计问题怎么解决

时间:2026-01-26 14:20:54
背景:

数据库中逗号拼接的字符串,想展示其完整拼接名称或者按其值统计处理,怎么做?

FIND_IN_SET函数和GROUP_CONCAT函数你会用吗?

一、查询问题

eg两张表 t_conclusion_detail(拜访信息表) 和 t_conclusion_info(拜访结论表)

t_conclusion_detail:

iduserNameconclusionIds
781918060586991616梦琪1,3
781986564770103296西施3
781989822074978304火舞2,3,4

t_conclusion_info:

conclusionIdconclusionName
1已成交
2暂无兴趣
3需要跟进
4沟通顺利

想要的效果:

iduserNameconclusionIdsconclusionNameStr
781918060586991616梦琪1,3已成交,需要跟进
781986564770103296西施3需要跟进
781989822074978304火舞2,3,4暂无兴趣,需要跟进,沟通顺利

思考:

一般这种情况两种方案:要么代码层面处理,要么数据库层面处理

1、方案一( 代码层面):先查拜访信息表,将数据返回到服务器,在代码里进行切割,然后再去拜访结论表里面去查询对应的名称,返回到程序进行处理拼接。造成频繁访问数据库,或需要批量查回再匹配处理,这样做虽然很简单也很好理解但是效率太低。

2、方案二(数据库):以mysql为例,使用FIND_IN_SET函数和GROUP_CONCAT函数进行查询,但是数据量特别大时可能不友好,利用不上索引等

SELECTs.id,s.user_nameuserName,s.conclusion_idsconclusionIds,(SELECTGROUP_CONCAT(user_name)FROMt_conclusion_infotrWHEREFIND_IN_SET(tr.conclusion_id,(SELECTconclusion_idsFROMt_conclusion_detailWHEREid=s.id)))ASconclusionNameStrFROMt_conclusion_details

tip:如果数据量特别大建议还是设计时不要逗号拼接设计,改成多表联查,或者使用代码层面处理

二、统计问题

还是上述两张表,想要的效果是每个结论出现频次的统计,即统计逗号拼接的字符串中内容

伪代码,具体根据情况拼接业务sql:

SELECTsum(casewhenfind_in_set('1',conclusion_ids)>0then1else0end)one,sum(casewhenfind_in_set('2',conclusion_ids)>0then1else0end)two,sum(casewhenfind_in_set('3',conclusion_ids)>0then1else0end)three,sum(casewhenfind_in_set('4',conclusion_ids)>0then1else0end)fourfromt_conclusion_detail

结果:

onetwothreefour
1131
三、效率问题

思考????: 模拟插入20万数据,查看find_in_set效率问题:

CREATETABLE`t_conclusion_detail`(`id`bigintunsignedNOTNULLAUTO_INCREMENTCOMMENT'主键',`user_name`varchar(32)COMMENT'姓名',`conclusion_ids`varchar(32)COMMENT'拜访结论(多个结论逗号分隔)'PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=1COMMENT='拜访记录表';
DROPPROCEDUREIFEXISTS`t_conclusion_detail_memory`DELIMITER//CREATEPROCEDURE`t_conclusion_detail_memory`(INnINT)BEGINDECLAREiINTDEFAULT1;DECLAREidINTDEFAULT1;DECLAREnum1INTDEFAULT1;DECLAREnum2INTDEFAULT1;DECLAREnum3INTDEFAULT1;WHILEi<nDOSETid=i;SETnum1=FLOOR(0+RAND()*6);SETnum2=FLOOR(0+RAND()*6);SETnum3=FLOOR(0+RAND()*6);INSERTINTO`t_conclusion_detail`VALUES(id,'test',concat(num1,',',num2,',',num3),);SETi=i+1;ENDWHILE;END//DELIMITER;--改回默认的MySQLdelimiter:';'CALLt_conclusion_detail_memory(200000);

经实验,20w数据时相关查询最慢2s左右,可接受范围。


上一篇:SQL中的笛卡尔积语法怎么应用
下一篇:MySQL订单ID是怎么生成的
mysql
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器
  • 英特尔第五代 Xeon CPU 来了:详细信息和行业反应
  • 由于云计算放缓引发扩张担忧,甲骨文股价暴跌
  • Web开发状况报告详细介绍可组合架构的优点
  • 如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳
  • 美光在数据中心需求增长后给出了强有力的预测
  • 2027服务器市场价值将接近1960亿美元
  • 生成式人工智能的下一步是什么?
  • 分享在外部存储上安装Ubuntu的5种方法技巧
  • 全球数据中心发展的关键考虑因素
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器

    英特尔第五代 Xeon CPU 来了:详细信息和行业反应

    由于云计算放缓引发扩张担忧,甲骨文股价暴跌

    Web开发状况报告详细介绍可组合架构的优点

    如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳

    美光在数据中心需求增长后给出了强有力的预测

    2027服务器市场价值将接近1960亿美元

    生成式人工智能的下一步是什么?

    分享在外部存储上安装Ubuntu的5种方法技巧

    全球数据中心发展的关键考虑因素