MYSQL: How to copy an entire row from one table to another in mysql with the second table having one extra column?

Mysql

Mysql Problem Overview


I have two tables with identical structure except for one column... Table 2 has an additional column in which I would insert the CURRENT_DATE()

I would like to copy all the values from table1 to table2.

If I use

INSERT INTO dues_storage SELECT * FROM dues WHERE id=5;

it throws an error pointing to the difference in the number of columns.

I have two questions:

  1. How do I get around this?
  2. How do I add the value for the additional date column (CURRENT_DATE()) in table2 within this same statement?

Mysql Solutions


Solution 1 - Mysql

To refine the answer from Zed, and to answer your comment:

INSERT INTO dues_storage
SELECT d.*, CURRENT_DATE()
FROM dues d
WHERE id = 5;

See T.J. Crowder's comment

Solution 2 - Mysql

The safest way to do it is to fully specify the columns both for insertion and extraction. There's no guarantee (to the application) that either of these will be the order you think they may be.

insert into dues_storage (f1, f2, f3, cd)
    select f1, f2, f3, current_date() from dues where id = 5;

If you're worried about having to change many multiple PHP pages that do this (as you seem to indicate in the comment to another answer), this is ripe for a stored procedure. That way, all your PHP pages simply call the stored procedure with (for example) just the ID to copy and it controls the actual copy process. That way, there's only one place where you need to maintain the code, and, in my opinion, the DBMS is the right place to do it.

Solution 3 - Mysql

INSERT INTO dues_storage
SELECT field1, field2, ..., fieldN, CURRENT_DATE()
FROM dues
WHERE id = 5;

Solution 4 - Mysql

Hope this will help someone... Here's a little PHP script I wrote in case you need to copy some columns but not others, and/or the columns are not in the same order on both tables. As long as the columns are named the same, this will work. So if table A has [userid, handle, something] and tableB has [userID, handle, timestamp], then you'd "SELECT userID, handle, NOW() as timestamp FROM tableA", then get the result of that, and pass the result as the first parameter to this function ($z). $toTable is a string name for the table you're copying to, and $link_identifier is the db you're copying to. This is relatively fast for small sets of data. Not suggested that you try to move more than a few thousand rows at a time this way in a production setting. I use this primarily to back up data collected during a session when a user logs out, and then immediately clear the data from the live db to keep it slim.

 function mysql_multirow_copy($z,$toTable,$link_identifier) {
    		$fields = "";
    		for ($i=0;$i<mysql_num_fields($z);$i++) {
    			if ($i>0) {
    				$fields .= ",";
    			}
    			$fields .= mysql_field_name($z,$i);
    		}
    		$q = "INSERT INTO $toTable ($fields) VALUES";
    		$c = 0;
    		mysql_data_seek($z,0); //critical reset in case $z has been parsed beforehand. !
    		while ($a = mysql_fetch_assoc($z)) {
    			foreach ($a as $key=>$as) {
    				$a[$key] = addslashes($as);
    				next ($a);
    			}
    			if ($c>0) {
    				$q .= ",";
    			}
    			$q .= "('".implode(array_values($a),"','")."')";
    			$c++;
    		}
    		$q .= ";";
    		$z = mysql_query($q,$link_identifier);
    		return ($q);
    	}

Solution 5 - Mysql

Alternatively, you can use Inner Queries to do so.

SQL> INSERT INTO <NEW_TABLE> SELECT * FROM CUSTOMERS WHERE ID IN (SELECT ID FROM <OLD_TABLE>);

Hope this helps!

Solution 6 - Mysql

SET @sql = 
CONCAT( 'INSERT INTO <table_name> (', 
	(
		SELECT GROUP_CONCAT( CONCAT('`',COLUMN_NAME,'`') ) 
			FROM information_schema.columns 
			WHERE table_schema = <database_name>
				AND table_name = <table_name>
				AND column_name NOT IN ('id')
    ), ') SELECT ', 
	( 
		SELECT GROUP_CONCAT(CONCAT('`',COLUMN_NAME,'`')) 
		FROM information_schema.columns 
		WHERE table_schema = <database_name>
			AND table_name = <table_source_name>
			AND column_name NOT IN ('id')  
    ),' from <table_source_name> WHERE <testcolumn> = <testvalue>' );  

PREPARE stmt1 FROM @sql; 
execute stmt1;

Of course replace <> values with real values, and watch your quotes.

Solution 7 - Mysql

Just wanted to add this little snippet which works beautifully for me.

INSERT INTO your_target_table SELECT * FROM your_rescource_table WHERE id = 18;

And while I'm at it give a big shout out to Sequel Pro, if you're not using it I highly recommend downloading it...makes life so much easier

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser165242View Question on Stackoverflow
Solution 1 - MysqlcrunchdogView Answer on Stackoverflow
Solution 2 - MysqlpaxdiabloView Answer on Stackoverflow
Solution 3 - MysqlZedView Answer on Stackoverflow
Solution 4 - MysqlJosh StrikeView Answer on Stackoverflow
Solution 5 - MysqlPrasheelView Answer on Stackoverflow
Solution 6 - MysqlJoseph CardwellView Answer on Stackoverflow
Solution 7 - MysqlKevin FView Answer on Stackoverflow