这是一个想法:
获取需要使用LENGTH()分隔的总价值:
以第一个例子[1,2,4,5]为例。这里有 4 个用逗号分隔的值。如果我们做LENGTH(value),我们将得到9,因为有9个字符,包括[和,。然后我们执行LENGTH(REPLACE(value,',','')),我们将值中的逗号替换为空,这将给我们6。如果我们减去它们,我们将得到3,我们假设得到4,所以我们在最终计算中加上+1。我们最终会得到这样的结果:
(LENGTH(value)-LENGTH(REPLACE(value, ',', '' )))+1
这样,您将获得ae 和4 和ac 和2。从这里有此信息的三种用途:
- 根据我们得到的最大数字来创建一个编号序列,在本例中为
4。
- 根据
value 列的长度返回重复的行。
- 用于
SUBSTRING_INDEX()函数并相应返回值。
最后,我设法使用相同的想法创建了两个查询,但使用了不同的 MySQL 版本。
对于较旧的 MySQL 版本(v8 之前),可能会这样做:
SELECT id,
SUBSTRING_INDEX(SUBSTRING_INDEX(val,',',ln),',',-1) AS value
FROM
(SELECT 1 AS ln UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) RN
LEFT JOIN
(SELECT id,
REPLACE(REPLACE(value,'[',''),']','') AS val
FROM tableA) A
ON ln<=(LENGTH(val)-LENGTH(REPLACE(val,',','')))+1
ORDER BY id, value;
但是,这里的问题是查询..(SELECT 1 AS ln UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) RN.. 的这一部分上的硬编码编号顺序。这意味着如果有一个value的长度是不断变化的,那么这部分需要不断地编辑。
对于 MySQL v8(但不完全支持 JSON_TABLE 的 v8.0.4):
WITH RECURSIVE cte AS (
SELECT 1 AS ln, MAX((length(value)-length(replace(value,',','')))+1) AS totval
from tableA UNION ALL
SELECT ln+1, totval FROM cte WHERE ln+1 <= totval)
SELECT id,
REGEXP_REPLACE(SUBSTRING_INDEX(SUBSTRING_INDEX(value,',',ln),',',-1),'[^0-9]','') AS value
FROM cte
LEFT JOIN tableA
ON ln<=(length(value)-length(replace(value,',','')))+1
ORDER BY id, value;
这里我使用WITH RECURSIVE函数来动态生成编号序列,也就是说如果长度大于4,则不需要编辑查询。
Demo fiddle