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

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

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

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

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

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

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

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

Ответы [ 7 ]

86 голосов
/ 30 августа 2009

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

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

См. T.J. Комментарий краудера

51 голосов
/ 30 августа 2009

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

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

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

8 голосов
/ 30 августа 2009
INSERT INTO dues_storage
SELECT field1, field2, ..., fieldN, CURRENT_DATE()
FROM dues
WHERE id = 5;
4 голосов
/ 10 ноября 2009

Надеюсь, это кому-нибудь поможет ... Вот небольшой PHP-скрипт, который я написал на тот случай, если вам нужно скопировать некоторые столбцы, но не другие, и / или столбцы не в одинаковом порядке в обеих таблицах. Пока столбцы названы одинаково, это будет работать. Таким образом, если таблица A имеет [userid, handle, что-то], а tableB имеет [userID, handle, timestamp], тогда вы «ВЫБЕРИТЕ userID, handle, NOW () в качестве метки времени FROM tableA», затем получите результат этого и передать результат в качестве первого параметра этой функции ($ z). $ 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);
        }
0 голосов
/ 30 марта 2018
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;

Конечно, замените <> значения реальными значениями и смотрите ваши кавычки.

0 голосов
/ 01 августа 2017

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

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

Надеюсь, это поможет!

0 голосов
/ 11 февраля 2017

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

INSERT INTO your_target_table ВЫБРАТЬ * FROM your_rescource_table Где id = 18;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...