Mysql逗号拼接字符串的关联查询以及统计问题
作者:一只IT攻城狮 发布时间:2024-01-28 12:15:03
标签:逗号,拼接,字符串
背景:
数据库中逗号拼接的字符串,想展示其完整拼接名称或者按其值统计处理,怎么做?
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左右,可接受范围。
来源:https://blog.csdn.net/weixin_47061482/article/details/127690069


猜你喜欢
- 问题你正在试着使用正则表达式去匹配一大块的文本,而你需要跨越多行去匹配。解决方案这个问题很典型的出现在当你用点(.)去匹配任意字符的时候,忘
- 本文实例讲述了Python基于pygame模块播放MP3的方法。分享给大家供大家参考,具体如下:安装pygame(可参考:安装Python和
- 概述在进行网站爬取数据的时候,会发现很多网站都进行了反爬虫的处理,如JS加密,Ajax加密,反Debug等方法,通过请求获取数据和页面展示的
- 本文实例讲述了Python程序控制语句用法。分享给大家供大家参考,具体如下:1、换行在Python中默认换行结束一个语句而不是使用分号,而如
- MySQL存储过程与存储函数的相关概念存储函数和存储过程的主要区别:存储函数一定会有返回值的存储过程不一定有返回值存储过程和函数能后将复杂的
- 迄今为止,导出/导入工具集仍是跨多个平台转移数据所需劳动强度最小的首选实用工具,尽管人们常常抱怨它速度太慢。导入只是将每条记录从导出转储文件
- 最近遇到这样的问题,在MySQL的存储过程中,游标操作时,需要执行一个conitnue的操作.众所周知,MySQL中的游标循环操作常用的有三
- 如何实现自定义一个异常python内置了许多异常类,为编写代码划定红线,才使调试代码时能及时发现错误。那么我们编写一个模块也可以为使用此模块
- 前言我们在处理数据库的问题的时候,有时在数据库端看不到异常的等待,但是应用却报连接异常。这种情况,有可能是在压力还没有传递到数据库,在网络这
- order by 查询语句使用也是非常频繁,有时候数据量大了会发现排序查询很慢,本文就介绍一下 MySQL 是如何进行排序的,以及如何利用其
- 1、打开Sqlserver,选择登录名下的账户右击点击属性2、右击点击属性查看强制过期是否被勾选上,如勾选上,会在一段时间后该账户不能正常使
- 一、自定义MyComboBox# MyComboBox.pyfrom PyQt5.QtWidgets import QComboBoxfro
- 在使用数据库的时候,难免要在使用过程中进行删除的操作,如果是使用int类型的字段,令其自增长,这是个最简单的办法,但是后果会有些不是你想要的
- 本文介绍基于Python语言,针对一个文件夹下大量的Excel表格文件,基于其中每一个文件,随机从其中选取一部分数据,并将全部文件中随机获取
- 界面设计页面引用了youzan组件进行设计,包括icon,button,tag,toast以及布局github地址:https://gith
- 本文是 《用 Golang 实现一个 Redis》系列文章第二篇,本文将分别介绍Redis 通信协议 以及 协议解析器 的实现,若您对协议有
- Python Socket模块中包含一些有用IP转换函数,说明如下:socket.ntohl(x) // 类似于
- 首先,如果以前安装的话,要删除干净。我也找了
- 前言:在前面一些文章中,经常能看到介绍某某参数的作用,可能有些小伙伴仍搞不清楚 MySQL 参数是啥。本篇文章我们来聊聊 MySQL 参数,
- 前言本文主要给大家介绍了关于python图片添加半透明水印的相关资料,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧示例代码