MYSQL: Як скопіювати цілий рядок з однієї таблиці в іншу в mysql, а друга таблиця має один додатковий стовпець?


76

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

Я хотів би скопіювати всі значення з table1 в table2.

якщо я використовую

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

він видає помилку, вказуючи на різницю в кількості стовпців.

У мене є два запитання щодо цього:

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

Ви могли б поглянути на це. Це спрацювало для мене в mysql. stackoverflow.com/questions/57168 / ...
Shreyo

Відповіді:


96

Щоб уточнити відповідь Зеда та відповісти на ваш коментар:

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

Див. Коментар TJ Crowder


51
Будьте ДУЖЕ ОБЕРЕЖНІ, роблячи це. Це працює, але припускає, що порядок стовпців у двох таблицях однаковий; він не збігається за назвою стовпця і намагається примусити значення до розміру, що може спричинити несподівані результати. Тепер, якщо ваша структура розробки запевняє, що порядки стовпців однакові для останнього стовпця, це зручний і простий спосіб це зробити, але застереження важливо.
TJ Crowder

На щастя порядок той самий. погано пам’ятайте, щоб зберегти структуру ідентичною навіть у майбутньому. Дякую всім!
user165242

@crunchdog як повинен бути організований запит , якщо мені потрібно , щоб встановити , whereяк A.id = B.id?
Євген

2
Вам навіть потрібен CURRENT_DATE ()? Ви можете встановити тип цього поля на TimeStamp і встановити за замовчуванням CURRENT_TIMESTAMP. Він повинен заповнити поточний DateTime до дати створення запису.
Chiwda

53

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

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

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


так .. але я тільки починаю. Мені зараз потрібно з’ясувати, що таке збережені процедури, дякую! ще одне, чого навчитися сьогодні!
user165242

1
це найкраща відповідь
Майк Волмар,

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

у таблиці так багато полів, чи є коротший шлях? Якщо я зміню там структуру таблиці, мені доведеться пам’ятати про зміну сторінок php.
user165242

ви можете врятуватися від цього зборами. *
Зед

4

Сподіваюся, це комусь допоможе ... Ось невеликий PHP-скрипт, який я написав на випадок, якщо вам потрібно скопіювати деякі стовпці, але не інші, та / або стовпці не в однаковому порядку в обох таблицях. Поки стовпці називаються однаково, це буде працювати. Отже, якщо таблиця A має [ідентифікатор користувача, дескриптор, щось], а таблиця B має [ідентифікатор користувача, дескриптор, позначку часу], тоді ви б "ВИБРАТИ userID, handle, NOW () як мітку часу З таблиці A", тоді отримаєте результат цього, і передайте результат як перший параметр цій функції ($ 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

Ви також можете використовувати для цього Внутрішні запити.

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

Сподіваюся, це допомагає!


0
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;

Звичайно, замініть значення <> реальними значеннями та стежте за цитатами.


-3

Просто хотів додати цей маленький фрагмент, який чудово працює для мене.

ВСТАВЛІТЬ У свою таблицю_цілей_ВИБЕРИТЬ * З таблиці_ресурсів_ДЕ, де = 18;

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.