将 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]>
我 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]>