Mysql: 插入多个带订单号的值
Mysql: insert multiple values with order number
我想拆分像 ('abc', 'dev', dfg') 这样的字符串并插入到 table 中,其订单号如下:
index value
1 abc
2 dev
3 dfg
无论如何我可以在 mysql 中做到这一点吗?尺寸未知。
你或许可以这样做:
WITH RECURSIVE cte AS (
SELECT 1 idx, LENGTH(REGEXP_REPLACE(stringVal,'[^,]',''))+1 AS maxLen
FROM mytable UNION
SELECT idx+1, maxLen FROM cte WHERE idx+1 <= maxLen)
SELECT idx,
SUBSTRING_INDEX(SUBSTRING_INDEX(stringVal,',',idx),',',-1) AS val
FROM cte
CROSS JOIN mytable;
根据列中用逗号分隔的字符串数量,使用 cte
生成 idx
。步骤是:
- 使用
REGEXP_REPLACE()
替换任何不是逗号的值; returns ,,
.
- 在正则表达式上使用
LENGTH()
得到逗号总数; returns 2
.
- 将长度结果加 1 (+1) returned;最终值
3
.
cte
结果是:
+-----+--------+
| idx | maxLen |
+-----+--------+
| 1 | 3 |
| 2 | 3 |
| 3 | 3 |
+-----+--------+
从生成的 cte
中,我们将使用 idx
值和 SUBSTRING_INDEX()
将 comma-separated、single-row 字符串分成多行.
了解查询在做什么:
这一点,我们可以模拟 3 个相同的查询重复 UNION ALL
在一起,如下所示:
SELECT 1 AS 'index',
SUBSTRING_INDEX(SUBSTRING_INDEX(stringVal,',',1),',',-1) AS val
FROM mytable
UNION ALL
SELECT 2,
SUBSTRING_INDEX(SUBSTRING_INDEX(stringVal,',',2),',',-1)
FROM mytable
UNION ALL
SELECT 3,
SUBSTRING_INDEX(SUBSTRING_INDEX(stringVal,',',3),',',-1)
FROM mytable;
也可以这样做;与 cte
方法相同的想法:
SELECT idx,
SUBSTRING_INDEX(SUBSTRING_INDEX(stringVal,',',idx),',',-1) AS val
FROM (SELECT 1 idx UNION
SELECT 2 UNION
SELECT 3 ) i
CROSS JOIN mytable;
这两个查询 return 与 cte
方法相同的结果,但它不是理想的方法;因为我们必须手动检查有多少字符串以逗号分隔并在查询中定义 (hard-code)。想象一下,如果一行字符串由 a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
之类的东西组成——所有 26 个字母表;那么这意味着 UNION
查询需要重复 26 次。
我想拆分像 ('abc', 'dev', dfg') 这样的字符串并插入到 table 中,其订单号如下:
index value
1 abc
2 dev
3 dfg
无论如何我可以在 mysql 中做到这一点吗?尺寸未知。
你或许可以这样做:
WITH RECURSIVE cte AS (
SELECT 1 idx, LENGTH(REGEXP_REPLACE(stringVal,'[^,]',''))+1 AS maxLen
FROM mytable UNION
SELECT idx+1, maxLen FROM cte WHERE idx+1 <= maxLen)
SELECT idx,
SUBSTRING_INDEX(SUBSTRING_INDEX(stringVal,',',idx),',',-1) AS val
FROM cte
CROSS JOIN mytable;
根据列中用逗号分隔的字符串数量,使用 cte
生成 idx
。步骤是:
- 使用
REGEXP_REPLACE()
替换任何不是逗号的值; returns,,
. - 在正则表达式上使用
LENGTH()
得到逗号总数; returns2
. - 将长度结果加 1 (+1) returned;最终值
3
. cte
结果是:
+-----+--------+
| idx | maxLen |
+-----+--------+
| 1 | 3 |
| 2 | 3 |
| 3 | 3 |
+-----+--------+
从生成的 cte
中,我们将使用 idx
值和 SUBSTRING_INDEX()
将 comma-separated、single-row 字符串分成多行.
了解查询在做什么:
这一点,我们可以模拟 3 个相同的查询重复 UNION ALL
在一起,如下所示:
SELECT 1 AS 'index',
SUBSTRING_INDEX(SUBSTRING_INDEX(stringVal,',',1),',',-1) AS val
FROM mytable
UNION ALL
SELECT 2,
SUBSTRING_INDEX(SUBSTRING_INDEX(stringVal,',',2),',',-1)
FROM mytable
UNION ALL
SELECT 3,
SUBSTRING_INDEX(SUBSTRING_INDEX(stringVal,',',3),',',-1)
FROM mytable;
也可以这样做;与 cte
方法相同的想法:
SELECT idx,
SUBSTRING_INDEX(SUBSTRING_INDEX(stringVal,',',idx),',',-1) AS val
FROM (SELECT 1 idx UNION
SELECT 2 UNION
SELECT 3 ) i
CROSS JOIN mytable;
这两个查询 return 与 cte
方法相同的结果,但它不是理想的方法;因为我们必须手动检查有多少字符串以逗号分隔并在查询中定义 (hard-code)。想象一下,如果一行字符串由 a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
之类的东西组成——所有 26 个字母表;那么这意味着 UNION
查询需要重复 26 次。