将 CSV 样式的 varchar 列移动到新的 table

Moving a CSV-style varchar column into a new table

我 15 年前创建的数据库设计不佳。我有一个带有逗号分隔值字符串的 varchar 列:'5,8,13'。该字符串不包含空格和尾随逗号,但值的数量是可变的。我想要做的是创建一个新的 table 并将这些值与该行的 ID 配对移动到其中。假设以上值来自 ID 为 7 的行,结果将是 3 行:

[
   {7, 5}
   {7, 8}
   {7, 13}
]

查看现有数据集,该列有 1 到 6 个值。我发现这个线程显示了如何执行拆分字符串函数:Split value from one field to two

但坦率地说,我不知道如何将它变成一个单独的插页。如果这不是一个简单的任务,那么我会在 PHP 中写一些东西,即使它会是很多插入语句。

进一步说明,这里有两个table:

create table Table_A(
    id int auto_increment primary key,
    platforms varchar(255)
)

create table Table_B(
    id int auto_increment primary key,
    platform int not null
)

Table_A 是现有数据,其中平台列中的数据是数字“3,45”或“56,4”的逗号分隔值。这些数字指向另一个 table 中的索引。是的,我知道糟糕的设计,谢天谢地,从那以后我学得更好了。我想解析 Table_A 中平台字符串中的数字,并将它们与所述 Table_A 行的 ID 一起插入到 Table_B 中。

这是一个小查询。它只从 CSV 中拆分 6 个值。 如果连续有更多 VAls,则必须更改 UNION ALL

结果存储在单表中。

MariaDB [bernd]> DESCRIBE singletable;
+-----------+------------------+------+-----+---------+----------------+
| Field     | Type             | Null | Key | Default | Extra          |
+-----------+------------------+------+-----+---------+----------------+
| id        | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| rno       | int(11)          | YES  |     | NULL    |                |
| singleval | int(11)          | YES  |     | NULL    |                |
+-----------+------------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

MariaDB [bernd]> SELECT * FROM singletable;
Empty set (0.00 sec)

MariaDB [bernd]> 
MariaDB [bernd]> SELECT * FROM csvtable;
+----+----------+
| id | csvvals  |
+----+----------+
|  1 | 1,3,5    |
|  2 | 2,4      |
|  3 | 6        |
|  4 | 8,9      |
|  5 | 22,21,20 |
+----+----------+
5 rows in set (0.00 sec)

MariaDB [bernd]> 
MariaDB [bernd]> 
MariaDB [bernd]> INSERT INTO singletable (rno,singleval)
    -> SELECT id as rno , SUBSTRING_INDEX( SUBSTRING_INDEX(csvvals, ',', no) ,',',-1) singleval
    -> FROM csvtable
    -> CROSS JOIN (SELECT 1 as no UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6) as n
    -> WHERE no <= LENGTH(csvvals) - LENGTH(REPLACE(csvvals,',','')) +1
    -> ORDER BY id,no;
Query OK, 11 rows affected (0.01 sec)
Records: 11  Duplicates: 0  Warnings: 0

MariaDB [bernd]> SELECT * FROM singletable;
+----+------+-----------+
| id | rno  | singleval |
+----+------+-----------+
|  1 |    1 |         1 |
|  2 |    1 |         3 |
|  3 |    1 |         5 |
|  4 |    2 |         2 |
|  5 |    2 |         4 |
|  6 |    3 |         6 |
|  7 |    4 |         8 |
|  8 |    4 |         9 |
|  9 |    5 |        22 |
| 10 |    5 |        21 |
| 11 |    5 |        20 |
+----+------+-----------+
11 rows in set (0.02 sec)

MariaDB [bernd]>