MYSQL: Wie kopiere ich eine ganze Zeile in MySQL von einer Tabelle in eine andere, wobei die zweite Tabelle eine zusätzliche Spalte enthält?

76

Ich habe zwei Tabellen mit identischer Struktur bis auf eine Spalte ... Tabelle 2 enthält die zusätzliche Spalte, in die ich CURRENT_DATE () einfügen würde.

Ich möchte alle Werte von Tabelle1 nach Tabelle2 kopieren.

wenn ich benutze

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

Es wird ein Fehler ausgegeben, der auf den Unterschied in der Anzahl der Spalten hinweist.

Ich habe zwei Fragen dazu:

  1. Wie komme ich darum herum?
  2. und wie füge ich den Wert für die zusätzliche Datumsspalte (CURRENT_DATE ()) in Tabelle 2 innerhalb derselben Anweisung hinzu?
user165242
quelle
Sie könnten sich das ansehen. Es hat bei mir in MySQL funktioniert. stackoverflow.com/questions/57168/…
Shreyo

Antworten:

96

Um die Antwort von Zed zu verfeinern und Ihren Kommentar zu beantworten:

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

Siehe den Kommentar von TJ Crowder

Crunchdog
quelle
51
Seien Sie dabei sehr vorsichtig . Es funktioniert, setzt jedoch voraus, dass die Reihenfolge der Spalten in den beiden Tabellen identisch ist. Es stimmt nicht mit dem Spaltennamen überein und versucht, die Anpassung der Werte zu erzwingen, was zu unerwarteten Ergebnissen führen kann. Wenn Ihre Entwicklungsstruktur sicherstellt, dass die Spaltenreihenfolgen bis auf die letzte Spalte identisch sind, ist dies eine bequeme und unkomplizierte Methode, aber die Einschränkung ist wichtig.
TJ Crowder
Zum Glück ist die Reihenfolge gleich. Ich denke daran, die Struktur auch in Zukunft identisch zu halten. Danke an alle!
user165242
@crunchdog wie sollte Abfrage organisiert werden , wenn ich festlegen müssen , wherewie A.id = B.id?
Eugene
2
Benötigen Sie überhaupt CURRENT_DATE ()? Sie können den Typ dieses Felds auf TimeStamp und den Standardwert auf CURRENT_TIMESTAMP setzen. Es sollte die aktuelle DateTime bis zum Zeitpunkt der Erstellung des Datensatzes angeben.
Chiwda
53

Am sichersten ist es, die Spalten sowohl zum Einfügen als auch zum Extrahieren vollständig anzugeben. Es gibt keine Garantie (für die Anwendung), dass eine dieser Optionen der Reihenfolge entspricht, von der Sie glauben, dass sie vorliegen.

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

Wenn Sie befürchten, dass Sie mehrere PHP-Seiten ändern müssen, die dies tun (wie Sie im Kommentar auf eine andere Antwort hinweisen), ist dies für eine gespeicherte Prozedur reif. Auf diese Weise rufen alle Ihre PHP-Seiten einfach die gespeicherte Prozedur mit (zum Beispiel) nur der zu kopierenden ID auf und steuern den eigentlichen Kopiervorgang. Auf diese Weise gibt es nur einen Ort, an dem Sie den Code pflegen müssen, und meiner Meinung nach ist das DBMS der richtige Ort dafür.

paxdiablo
quelle
Ja, aber ich fange gerade erst an. Ich muss jetzt herausfinden, was gespeicherte Prozeduren sind, danke! eine weitere Sache, die Sie heute lernen müssen!
user165242
1
Dies ist die beste Antwort
Mike Volmar
8
INSERT INTO dues_storage
SELECT field1, field2, ..., fieldN, CURRENT_DATE()
FROM dues
WHERE id = 5;
Zed
quelle
Es gibt so viele Felder in der Tabelle, gibt es kürzere Wege? Wenn ich dort die Tabellenstruktur ändere, müsste ich daran denken, auch die PHP-Seiten zu ändern.
user165242
Sie können es mit Gebühren entkommen. *
Zed
4

Hoffe, das hilft jemandem ... Hier ist ein kleines PHP-Skript, das ich geschrieben habe, falls Sie einige Spalten kopieren müssen, andere jedoch nicht, und / oder die Spalten in beiden Tabellen nicht in derselben Reihenfolge sind. Solange die Spalten den gleichen Namen haben, funktioniert dies. Wenn also Tabelle A [Benutzer-ID, Handle, etwas] und Tabelle B [Benutzer-ID, Handle, Zeitstempel] hat, würden Sie "Benutzer-ID, Handle, JETZT () als Zeitstempel VON Tabelle A AUSWÄHLEN" und dann das Ergebnis erhalten Übergeben Sie das Ergebnis als ersten Parameter an diese Funktion ($ z). $ toTable ist ein Zeichenfolgenname für die Tabelle, in die Sie kopieren, und $ link_identifier ist die Datenbank, in die Sie kopieren. Dies ist für kleine Datenmengen relativ schnell. Es wird nicht empfohlen, auf diese Weise in einer Produktionsumgebung mehr als ein paar tausend Zeilen gleichzeitig zu verschieben.

 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);
        }
Josh Strike
quelle
0

Alternativ können Sie dazu Inner Queries verwenden.

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

Hoffe das hilft!

Prasheel
quelle
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;

Ersetzen Sie natürlich <> Werte durch echte Werte und achten Sie auf Ihre Anführungszeichen.

Joomsavvy
quelle
-3

Ich wollte nur diesen kleinen Ausschnitt hinzufügen, der wunderbar für mich funktioniert.

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

Und während ich gerade dabei bin, gebe ich Sequel Pro einen großen Gruß. Wenn Sie es nicht verwenden, empfehle ich dringend, es herunterzuladen ... macht das Leben so viel einfacher

Kevin F.
quelle