MYSQL: как скопировать всю строку из одной таблицы в другую в mysql со второй таблицей, имеющей один дополнительный столбец?


У меня есть две таблицы с одинаковой структурой, за исключением одного столбца... В таблице 2 есть дополнительный столбец, в который я бы вставил CURRENT_DATE ()

Я хотел бы скопировать все значения из таблицы 1 в таблицу 2.

если я использую

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

он выдает ошибку указывая на разницу в количестве столбцов.

У меня есть два вопроса по этому поводу:

  1. как мне обойти это?
  2. и как мне это сделать добавить значение для дополнительного столбца даты (CURRENT_DATE ()) в таблице 2 в этом же операторе?
7 69

7 ответов:

чтобы уточнить ответ от Zed, и ответить на ваш комментарий:

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

см. комментарий Ти Джея Краудера

самый безопасный способ сделать это-полностью указать столбцы как для вставки, так и для извлечения. Там нет никакой гарантии (для приложения), что любой из них будет порядок, который вы думаете, что они могут быть.

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

Если вы беспокоитесь о том, чтобы изменить много нескольких страниц PHP, которые делают это (как вы, кажется, указываете в комментарии к другому ответу), это созрело для хранимой процедуры. Таким образом, все ваши страницы PHP просто вызывают хранимую процедуру с (например) только Идентификатор для копирования, и он управляет фактическим процессом копирования. Таким образом, есть только одно место, где вам нужно поддерживать код, и, на мой взгляд, СУБД-это правильное место для этого.

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

надеюсь, что это поможет кому-то... Вот небольшой PHP-скрипт, который я написал на случай, если вам нужно скопировать некоторые столбцы, но не другие, и/или столбцы не в том же порядке на обеих таблицах. Пока столбцы называются одинаково, это будет работать. Так, если стол имеет [идентификатор пользователя, ручка, что-то] и tableb и [идентификатор пользователя, ручка, штамп времени], и тогда ты "выберите имя пользователя, ручка, а теперь() в качестве метки времени из таблицы tablea", то получите результат, что и передать результат в качестве первого параметра этой функции ($Зет.) $toTable-это имя строки для таблицы, в которую вы копируете, а $link_identifier-это БД, в которую вы копируете. Это относительно быстро для небольших наборов данных. Не рекомендуется пытаться переместить более нескольких тысяч строк за один раз таким образом в производственной среде. Я использую это в первую очередь для резервного копирования данных, собранных во время сеанса, когда пользователь выходит из системы, а затем сразу же очищает данные из живой БД, чтобы сохранить его тонким.

 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);
        }

кроме того, для этого можно использовать внутренние запросы.

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

надеюсь, что это помогает!

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;

конечно, замените значения на реальные значения и следите за своими котировками.

просто хотел добавить этот маленький фрагмент, который прекрасно работает для меня.

вставить в your_target_table ВЫБИРАТЬ * Из your_rescource_table Где id = 18;

и пока я нахожусь на нем, дайте большой крик Sequel Pro, Если вы его не используете, я настоятельно рекомендую загрузить его...делает жизнь намного проще!--1-->