这不是工作,
DB但有可能:
CREATE TABLE tab(id INT, col VARCHAr(100));INSERT INTO tab(id, col) VALUES (1, 'option[A]sum[A]g3et[B]'), (2, '[Cosi]sum[A]g3et[ZZZZ]'); SELECt DISTINCT *FROM ( SELECt id, RIGHt(val, LENGTH(val) - LOCATE('[', val)) AS val FROM ( SELECt id, SUBSTRING_INDEX(SUBSTRING_INDEX(t.col, ']', n.n), ']', -1) AS val FROM tab t CROSS JOIN ( SELECt a.N + b.N * 10 + 1 n FROM (SELECt 0 AS N UNIOn ALL SELECT 1 UNIOn ALL SELECT 2 UNIOn ALL SELECT 3 UNIOn ALL SELECT 4 UNIOn ALL SELECT 5 UNIOn ALL SELECT 6 UNIOn ALL SELECT 7 UNIOn ALL SELECT 8 UNIOn ALL SELECT 9) a ,(SELECT 0 AS N UNIOn ALL SELECT 1 UNIOn ALL SELECT 2 UNIOn ALL SELECT 3 UNIOn ALL SELECT 4 UNIOn ALL SELECT 5 UNIOn ALL SELECT 6 UNIOn ALL SELECT 7 UNIOn ALL SELECT 8 UNIOn ALL SELECT 9) b ) n WHERe n.n <= 1 + (LENGTH(t.col) - LENGTH(REPLACE(t.col, ']', ''))) ) sub) sWHERe val <> ''ORDER BY ID;笔记:
根据col最大长度,您可能需要在CROSS JOIN部分中生成更多数字。现在最多可以有100个。
输出:
在此处输入图片说明
这个怎么运作:
- 生成编号表 CROSS JOIN
- 根据]定界符分割字符串
RIGHt(val, LENGTH(val) - LOCATE('[', val))删除部分直到 [- 筛选出空记录
- 仅获DISTINCT取值
最内层查询:
╔════╦══════════╗║ id ║ val ║╠════╬══════════╣║ 1 ║ option[A ║║ 1 ║ sum[A ║║ 1 ║ g3et[B ║║ 1 ║ ║╚════╩══════════╝
第二个子查询:
╔════╦═════╗║ id ║ val ║╠════╬═════╣║ 1 ║ A ║║ 1 ║ A ║║ 1 ║ B ║║ 1 ║ ║╚════╩═════╝
最外层的查询:
╔════╦═════╗║ id ║ val ║╠════╬═════╣║ 1 ║ A ║║ 1 ║ B ║╚════╩═════╝
我需要每行查询的结果..不合并
因此添加简单:
WHERe n.n <= 1 + (LENGTH(t.col) - LENGTH(REPLACE(t.col, ']', ''))) AND t.id = ?
编辑2:
请参阅http://sqlfiddle.com/#!9/8ee95/1,您的查询对我的数据有部分作用。我也将类型更改为longtext。
您想在MySQL中解析JSON。正如我在解析并在应用程序层中获取价值之前所说的那样。该答案仅用于演示/玩具目的,并且性能会很差。
如果您仍然坚持使用SQL解决方案:
SELECT id, val,s.nFROM ( SELECt id, RIGHt(val, LENGTH(val) - LOCATE('[', val)) AS val,n FROM ( SELECt id, SUBSTRING_INDEX(SUBSTRING_INDEX(t.col, ']', n.n), ']', -1) AS val, n.n FROM (SELECt id, REPLACE(col, '[]','') as col FROM tab) t CROSS JOIN ( SELECt e.N * 10000 + d.N * 1000 + c.N * 100 + a.N + b.N * 10 + 1 n FROM (SELECT 0 AS N UNIOn ALL SELECT 1 UNIOn ALL SELECT 2 UNIOn ALL SELECT 3 UNIOn ALL SELECT 4 UNIOn ALL SELECT 5 UNIOn ALL SELECT 6 UNIOn ALL SELECT 7 UNIOn ALL SELECT 8 UNIOn ALL SELECT 9) a ,(SELECT 0 AS N UNIOn ALL SELECT 1 UNIOn ALL SELECT 2 UNIOn ALL SELECT 3 UNIOn ALL SELECT 4 UNIOn ALL SELECT 5 UNIOn ALL SELECT 6 UNIOn ALL SELECT 7 UNIOn ALL SELECT 8 UNIOn ALL SELECT 9) b ,(SELECT 0 AS N UNIOn ALL SELECT 1 UNIOn ALL SELECT 2 UNIOn ALL SELECT 3 UNIOn ALL SELECT 4 UNIOn ALL SELECT 5 UNIOn ALL SELECT 6 UNIOn ALL SELECT 7 UNIOn ALL SELECT 8 UNIOn ALL SELECT 9) c ,(SELECT 0 AS N UNIOn ALL SELECT 1 UNIOn ALL SELECT 2 UNIOn ALL SELECT 3 UNIOn ALL SELECT 4 UNIOn ALL SELECT 5 UNIOn ALL SELECT 6 UNIOn ALL SELECT 7 UNIOn ALL SELECT 8 UNIOn ALL SELECT 9) d ,(SELECT 0 AS N UNIOn ALL SELECT 1 UNIOn ALL SELECT 2 UNIOn ALL SELECT 3 UNIOn ALL SELECT 4 UNIOn ALL SELECT 5 UNIOn ALL SELECT 6 UNIOn ALL SELECT 7 UNIOn ALL SELECT 8 UNIOn ALL SELECT 9) e ) n WHERe n.n <= 1 + (LENGTH(t.col) - LENGTH(REPLACE(t.col, ']', ''))) ) sub) sWHERe val <> ''GROUP BY id, valHAVINg n <> MAX(n)ORDER BY id,n;SqlFiddleDemo输出:
╔═════╦═════════════╦════╗║ id ║ val ║ n ║╠═════╬═════════════╬════╣║ 1 ║ CE31285LV4 ║ 1 ║║ 1 ║ D32E ║ 3 ║║ 1 ║ GTX750 ║ 5 ║║ 1 ║ M256S ║ 7 ║║ 1 ║ H2X1T ║ 9 ║║ 1 ║ FMLANE4U4 ║ 11 ║╚═════╩═════════════╩════╝
编辑3:
在那里到底做了什么?你为什么需要
CROSS JOIN并且整个子查询仅是理货表格。就这些。如果MySQL具有产生数字序列的功能(如generate_series或预先填充的数字表),则不需要CROSS JOIN。
需要以下数字表SUBSTRING_INDEX:
SUBSTRING_INDEX(str,delim,count)
在出现定界符delim之前,从字符串str返回子字符串。如果count为正,则返回最后定界符左侧的所有内容(从左侧开始计数)。如果count为负,则返回最后定界符右边的所有内容(从右边开始计数)。搜索delim时,SUBSTRING_INDEX()执行区分大小写的匹配。



