Move a varchar column containing CSV format to another table
P粉478188786
P粉478188786 2023-09-10 19:59:25
0
1
513

The database I created 15 years ago was poorly designed. I have a varchar column containing comma separated strings: '5,8,13'. The string does not contain spaces and trailing commas, but the number of values ​​is variable. What I want to do is create a new table and move these values ​​paired with the row's ID into the new table. Assuming the above value comes from row with ID 7, the result will be 3 rows:

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

View the existing data set, the value of this column ranges from 1 to 6. I found a thread that shows how to use the split string function: Split value from one field to two

But frankly, I don't know how to translate this into a single insert operation. If this is not a simple task, then I will just write a PHP script, even if it will have many insert statements.

Further explanation, here are two tables:

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 is the existing data, where the data in the platforms column is the comma-separated numbers "3,45," or "56,4". These numbers point to an index in another table. Yes, I know it's a bad design, luckily I've learned a better way since then. I want to parse the numbers from Table_A's platform string and insert them into Table_B along with the Table_A row's ID.

P粉478188786
P粉478188786

reply all(1)
P粉956441054

Here is a small query to achieve this function. It only splits 6 values ​​from CSV. If there are more values ​​in a row you have to change UNION ALL

The results are stored in singletable.

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]>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template