Restructuring a bad database with PHP loops or MySQL

前端 未结 1 1387
甜味超标
甜味超标 2020-12-02 03:20

I have a special case with a PHP project where I am working with a database without a 3rd normal form structure. The database consists of only 1 table with loads of columns.

相关标签:
1条回答
  • 2020-12-02 03:41

    No PHP is needed. You can do it with pure MySQL code only.

    Create table/insert table

    CREATE TABLE HugeTable
        (`Column1` VARCHAR(11), `Column2` VARCHAR(11), `Column3` VARCHAR(11))
    ;
    
    INSERT INTO HugeTable
        (`Column1`, `Column2`, `Column3`)
    VALUES
        ('Data1;Data2', 'Data3;Data4', 'Data5;Data6')
    ; 
    
    CREATE TABLE NewTable
       (`Column1` VARCHAR(11), `Column2` VARCHAR(11), `Column3` VARCHAR(11))
    ;
    

    First we need MySQL to generate numbers. This MySQL code generates 1 to 100. So the final query will support up to 100 separated values.

    Query

    SELECT 
     @row := @row + 1 AS ROW
    FROM (
      SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
    ) row1
    CROSS JOIN (
      SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
    ) row2
    CROSS JOIN (
      SELECT @row := 0 
    ) init_user_params 
    

    Result

      row  
    --------
           1
           2
           3
           4
           5
           6
           7
           8
           9
          10
         ...
         ...
          90
          91
          92
          93
          94
          95
          96
          97
          98
          99
         100
    

    Now we can look at a method to separate on the ; delimiter. We can use nested SUBSTRING_INDEX functions for that

    Query

    SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('Data1;Data2', ';', 1), ';', -1) AS DATA
    

    Result

    data    
    --------
    Data1   
    

    You can see only the first word is returned if we want the second word we can use

    Query

    SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('Data1;Data2', ';', 2), ';', -1) AS DATA
    

    Result

    data    
    --------
    Data2  
    

    Now we combine the number generator and the SUBSTRING_INDEX to generate the data

    Query

    SELECT 
      DISTINCT
       SUBSTRING_INDEX(SUBSTRING_INDEX(Column1, ';', rows.row), ';', -1) Column1
     , SUBSTRING_INDEX(SUBSTRING_INDEX(Column2, ';', rows.row), ';', -1) Column2
     , SUBSTRING_INDEX(SUBSTRING_INDEX(Column3, ';', rows.row), ';', -1) Column3
    FROM (
      SELECT 
       @row := @row + 1 AS ROW
      FROM (
        SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
      ) row1
      CROSS JOIN (
        SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
      ) row2  
      CROSS JOIN (
        SELECT @row := 0 
      ) init_user_params
    )
     ROWS
    CROSS JOIN 
     HugeTable 
    

    Result

    Column1  Column2  Column3  
    -------  -------  ---------
    Data1    Data3    Data5    
    Data2    Data4    Data6    
    

    Query NewTable

    INSERT INTO 
      NewTable
    SELECT 
      DISTINCT
       SUBSTRING_INDEX(SUBSTRING_INDEX(Column1, ';', rows.row), ';', -1) Column1
     , SUBSTRING_INDEX(SUBSTRING_INDEX(Column2, ';', rows.row), ';', -1) Column2
     , SUBSTRING_INDEX(SUBSTRING_INDEX(Column3, ';', rows.row), ';', -1) Column3
    FROM (
      SELECT 
       @row := @row + 1 AS ROW
      FROM (
        SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
      ) row1
      CROSS JOIN (
        SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
      ) row2  
      CROSS JOIN (
        SELECT @row := 0 
      ) init_user_params
    )
     ROWS
    CROSS JOIN 
     HugeTable 
    

    Query

    SELECT * FROM NewTable
    

    Result

    Column1  Column2  Column3  
    -------  -------  ---------
    Data1    Data3    Data5    
    Data2    Data4    Data6   
    
    0 讨论(0)
提交回复
热议问题