MySQL分割一行为多行的思路

最近数据分析有需求,分析运营活动短信用户,但是发送短信的用户是通过 JSON 字符串数组存储在一个 text 字段的。内容类似于:

["user1", "user2", "user3"....]

数据分析想分析这些用户,那么就需要 in 这些用户查询。自己手动拼 SQL 太蛋疼,而且好几万几十万的用户,拼成SQL,复制粘贴也够蛋疼的。那么可以考虑将这一行分割为多行,作为一个字段。

mysql.help_topic 是啥

网上的思路是利用 mysql.help_topic 这个记录表,这个表是存储 mysql 各种帮助文档目录的,主要因为他有一个从零开始自增的 id 字段,所以采用这张表作为帮助表。其实他不是用来干这个的。并且,有时候我们精简安装,或者是云服务里面的 mysql,他们的这张表里面的内容,是空的,所以我们不能靠这张表。

如何自己实现呢?

思路主要是如下,首先处理数据,将 JSON 字符串数组处理成:

user1,user2,user3

通过:

select replace(replace(replace(replace(a,'[',''),']',''), '"', ''),' ','') processed_data from 表

然后,我们通过substring_index函数,可以提取出user1user2user3这些用户 id。分别是:substring_index(substring_index(processed_data,',',1),',',-1)substring_index(substring_index(processed_data,',',2),',',-1)substring_index(substring_index(processed_data,',',3),',',-1).可以看出,如果我们能提供一个数字,这个数字从1开始,一直到,的个数 + 1,这样就能使用substring_index函数,将每个 userId 提取出来,也就是将数据转换成:

1+-------------------+----+ 2| processed_data | id | 3| user1,user2,user3 | 1 | 4| user1,user2,user3 | 2 | 5| user1,user2,user3 | 3 |

哪里有这么一张表呢?我们可以创建一个表,里面只有一列 id,从0或者1开始,这里我们从0开始,一直到你的,可能的最多个数,我们这里是 200 万。

1+----+ 2| id | 3+----+ 4| 0 | 5| 1 | 6| 2 | 7| 3 | 8| 4 | 9| 5 |

这样,通过 join 这张表,用 id < ,的个数为条件,就能得出上面的processed_dataid join 的数据。

最后的SQL:

1SELECT 2 substring_index( substring_index( processed_data, ',', b.id + 1 ), ',',- 1 ) user_id 3FROM 4( 5SELECT REPLACE 6 ( 7 REPLACE ( REPLACE ( REPLACE (数据字段, '[', '' ), ']', '' ), '"', '' ), 8 ' ', 9 '' 10 ) processed_data 11FROM 1213) temp 14JOIN help表 b ON b.id < ( length( temp.processed_data ) - length( REPLACE ( temp.processed_data, ',', '' ) ) + 1 )

其中的 help 表就是里面只有一列 id,从0或者1开始,这里我们从0开始,一直到你的,可能的最多个数的这张表

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Python3:sqlalchemy对mysql数据库操作,非sql语句

Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''

Twitter的分布式自增ID算法snowflake (Java版)

概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移

MySQL分割一行为多行的思路 - HelloWorld