加入收藏 | 设为首页 | 会员中心 | 我要投稿 聊城站长网 (https://www.0635zz.com/)- 智能语音交互、行业智能、AI应用、云计算、5G!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

Mysql逗号拼接文件的关联数据及统计问题如何解决

发布时间:2023-07-05 15:08:57 所属栏目:MySql教程 来源:
导读:这篇“Mysql逗号拼接字符串的关联查询及统计问题怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,
这篇“Mysql逗号拼接字符串的关联查询及统计问题怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Mysql逗号拼接字符串的关联查询及统计问题怎么解决”文章吧。
 
背景:
 
数据库中逗号拼接的字符串,想展示其完整拼接名称或者按其值统计处理,怎么做?
 
FIND_IN_SET函数和GROUP_CONCAT函数你会用吗?
 
一、查询问题
 
eg两张表 t_conclusion_detail(拜访信息表) 和 t_conclusion_info(拜访结论表)
 
t_conclusion_detail:
 
id userName conclusionIds
 
781918060586991616 梦琪 1,3
 
781986564770103296 西施 3
 
781989822074978304 火舞 2,3,4
 
t_conclusion_info:
 
conclusionId conclusionName
 
1 已成交
 
2 暂无兴趣
 
3 需要跟进
 
4 沟通顺利
 
想要的效果:
 
id userName conclusionIds conclusionNameStr
 
781918060586991616 梦琪 1,3 已成交,需要跟进
 
781986564770103296 西施 3 需要跟进
 
781989822074978304 火舞 2,3,4 暂无兴趣,需要跟进,沟通顺利
 
思考:
 
一般这种情况两种方案:要么代码层面处理,要么数据库层面处理
 
1、方案一( 代码层面):先查拜访信息表,将数据返回到服务器,在代码里进行切割,然后再去拜访结论表里面去查询对应的名称,返回到程序进行处理拼接。造成频繁访问数据库,或需要批量查回再匹配处理,这样做虽然很简单也很好理解但是效率太低。
 
2、方案二(数据库):以mysql为例,使用FIND_IN_SET函数和GROUP_CONCAT函数进行查询,但是数据量特别大时可能不友好,利用不上索引等
 
SELECT
 
s.id,s.user_name userName,s.conclusion_ids conclusionIds,
 
(SELECT GROUP_CONCAT(user_name)
 
FROM t_conclusion_info tr
 
WHERE FIND_IN_SET(tr.conclusion_id,(SELECT conclusion_ids FROM t_conclusion_detail WHERE id=s.id))) AS conclusionNameStr
 
FROM t_conclusion_detail s
 
tip:如果数据量特别大建议还是设计时不要逗号拼接设计,改成多表联查,或者使用代码层面处理
 
二、统计问题
 
还是上述两张表,想要的效果是每个结论出现频次的统计,即统计逗号拼接的字符串中内容
 
伪代码,具体根据情况拼接业务sql:
 
SELECT
 
sum(case when find_in_set('1',conclusion_ids)>0  then 1 else 0 end) one,
 
sum(case when find_in_set('2',conclusion_ids) >0 then 1 else 0 end) two,
 
sum(case when find_in_set('3',conclusion_ids) >0 then 1 else 0 end) three,
 
sum(case when find_in_set('4',conclusion_ids) >0 then 1 else 0 end) four
 
from t_conclusion_detail
 
结果:
 
one two three four
 
1 1 3 1
 
三、效率问题
 
思考????: 模拟插入20万数据,查看find_in_set效率问题:
 
CREATE TABLE `t_conclusion_detail` (
 
   `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
 
   `user_name` varchar(32) COMMENT '姓名',
 
   `conclusion_ids` varchar(32) COMMENT '拜访结论(多个结论逗号分隔)'
 
  PRIMARY KEY (`id`)    
 
) ENGINE=InnoDB AUTO_INCREMENT=1 COMMENT='拜访记录表';
 
DROP PROCEDURE IF EXISTS `t_conclusion_detail_memory`
 
DELIMITER //
 
CREATE PROCEDURE `t_conclusion_detail_memory`(IN n INT)
 
BEGIN
 
    DECLARE i INT DEFAULT 1;
 
    DECLARE id INT DEFAULT 1;
 
    DECLARE num1 INT DEFAULT 1;
 
    DECLARE num2 INT DEFAULT 1;
 
    DECLARE num3 INT DEFAULT 1;
 
    WHILE i < n DO
 
        SET id = i;
 
        SET num1 = FLOOR(0 + RAND()*6);
 
        SET num2 = FLOOR(0 + RAND()*6);
 
        SET num3 = FLOOR(0 + RAND()*6);
 
        INSERT INTO `t_conclusion_detail` VALUES (id, 'test', concat(num1,',',num2,',',num3), );
 
        SET i = i + 1;
 
    END WHILE;
 
END //
 
DELIMITER ;  -- 改回默认的 MySQL delimiter:';'
 
CALL t_conclusion_detail_memory(200000);
 
经实验,20w数据时相关查询最慢2s左右,可接受范围。
 
 

(编辑:聊城站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!