Search code examples
mysqlrowsrecords

Add missing records into mysql table based on primary key


I have a mysql table with members, about 1400 records, and I am going to switch to a new membership software (amember v3 to amemberv4). The problem is that amember v4 is a whole new program so the database tables cannot have any missing records or it will reorder based on the primary key. For instance, membership ID in a members table which are associated with product IDs in a product table. There is a fact table that references this dimensions.

My problem is how to add in null records with a starting membership ID of those missing. For example the table begins with membership ID 4 instead of 1,2,3. I need help finding a solution to add these missing records based on membership ID's that are missing. I did make a second table based on the first one (membersold, members) as I am sure I need to join them on each other to create an update statement to add those missing records. There are about 7 columns that will be just null values.

Any ideas?


Solution

  • First of all: what both Jan Dvorak and Michael Berkowski said is absolutely true. Therefore, check carefully that you really need this hack, for chances are overwhelming that you don't.

    But just in case, just for the heck of it, this inserts all IDs into a table - provided they are primary keys, and that they don't already exist.

    Almost any other way is better (except maybe doing it by hand), but requires procedures in either MySQL or other languages.

    -- insert IDs from 1 to 1701, plus another field "otherfield" with value "othervalue"
    -- The maximum ID here is about 2400, but you said you needed at most 1400.
    -- And you can add 1000 instead of 1 to the value of 'id' and run it again
    -- to insert ids from 1000 to 2701 :-)
    
    INSERT IGNORE INTO yourtable
          (id, otherfield)
    SELECT id, 'othervalue'
    FROM (
        SELECT 1+a.x+b.x*7+c.x*49+d.x*343 AS id FROM
        ( SELECT 0 AS x UNION SELECT 1 UNION SELECT 2 UNION
          SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 ) AS a
        JOIN
        ( SELECT 0 AS x UNION SELECT 1 UNION SELECT 2 UNION
          SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 ) AS b
        JOIN
        ( SELECT 0 AS x UNION SELECT 1 UNION SELECT 2 UNION
          SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 ) AS c
        JOIN
        ( SELECT 0 AS x UNION SELECT 1 UNION SELECT 2 UNION
          SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 ) AS d
       ) AS generated
    WHERE generated.id < 1701;
    

    As I said, this is a very ugly way to do things.

    If you have any language available at all, you can generate the insert queries and run them, e.g. in bash:

    ( for id in $( seq 1 1400 ); do
        echo "INSERT IGNORE INTO mytable ( id, otherfield ) VALUES ( $id, 'hello' );"
    done ) | mysql databasename
    

    or in PHP, python, or Perl -- you just generate a SQL INSERT statement of the form

    INSERT IGNORE INTO mytable ( id ) VALUES ( ... );
    

    and fill in the blanks with an incrementing counter, then send the statement to the database. The IGNORE will skip the values that are already there. How you fill the blanks depends on the language you choose. If you need to populate other fields, enter the names after id and their default values after the blanks.