MySQL: Jak skopiować wiersze, ale zmienić kilka pól?

195

Mam dużą liczbę wierszy, które chciałbym skopiować, ale muszę zmienić jedno pole.

Mogę wybrać wiersze, które chcę skopiować:

select * from Table where Event_ID = "120"

Teraz chcę, aby skopiować wszystkie te wiersze i tworzyć nowe wiersze podczas ustawiania Event_IDsię 155. Jak mogę to osiągnąć?

Andrzej
źródło

Odpowiedzi:

279
INSERT INTO Table
          ( Event_ID
          , col2
           ...
          )
     SELECT "155"
          , col2
           ...
      FROM Table WHERE Event_ID = "120"

Tutaj col2, ... reprezentują pozostałe kolumny (te inne niż Event_ID) w twojej tabeli.

dcp
źródło
39
czy można to zrobić bez konieczności podawania nazw kolumn?
Andrew
4
Nie, że jestem świadomy. Oczywiście, jeśli twoja tabela ma około 1000 kolumn lub coś i nie chcesz wpisywać ich wszystkich, możesz napisać instrukcję SQL, aby zbudować instrukcję SQL :). Sposób, w jaki to zrobiłbyś, to użycie schematu_informacyjnego, aby uzyskać nazwy kolumn dla tabeli. Ale to naprawdę przesada, po prostu wpisałbym nazwy kolumn.
dcp
3
Czy byłoby to możliwe przy użyciu gwiazdki, aby uzyskać pozostałe kolumny?
Peter
2
Zalogowałem się, aby głosować, aby dowiedzieć się, że już to głosowałem. Myślę, że to uratowało mnie już kilka razy :) Dziękuję!
aexl
2
@Bitterblue - Przepraszam, nie rozumiem twojego komentarza. Nigdy nie mówiłem col2, ... były kolumnami, których nie chcesz kopiować, powiedziałem tylko, że reprezentują pozostałe kolumny z tabeli. Oczywiste jest, że zostaną one skopiowane, w przeciwnym razie w ogóle nie byłyby w instrukcji SQL.
dcp
140

Jest to rozwiązanie, w którym masz wiele pól w tabeli i nie chcesz, żebyś miał skurcze palca po wpisaniu wszystkich pól, wystarczy wpisać te potrzebne :)

Jak skopiować niektóre wiersze do tej samej tabeli, przy czym niektóre pola mają różne wartości:

  1. Utwórz tymczasową tabelę ze wszystkimi wierszami, które chcesz skopiować
  2. Zaktualizuj wszystkie wiersze w tabeli tymczasowej o żądane wartości
  3. Jeśli masz pole automatycznego przyrostu, powinieneś ustawić je na NULL w tabeli tymczasowej
  4. Skopiuj wszystkie wiersze tabeli tymczasowej do oryginalnej tabeli
  5. Usuń tabelę tymczasową

Twój kod:

CREATE table temporary_table AS SELECT * FROM original_table WHERE Event_ID="155";

UPDATE temporary_table SET Event_ID="120";

UPDATE temporary_table SET ID=NULL

INSERT INTO original_table SELECT * FROM temporary_table;

DROP TABLE temporary_table

Ogólny kod scenariusza:

CREATE table temporary_table AS SELECT * FROM original_table WHERE <conditions>;

UPDATE temporary_table SET <fieldx>=<valuex>, <fieldy>=<valuey>, ...;

UPDATE temporary_table SET <auto_inc_field>=NULL;

INSERT INTO original_table SELECT * FROM temporary_table;

DROP TABLE temporary_table

Kod uproszczony / skrócony:

CREATE TEMPORARY TABLE temporary_table AS SELECT * FROM original_table WHERE <conditions>;

UPDATE temporary_table SET <auto_inc_field>=NULL, <fieldx>=<valuex>, <fieldy>=<valuey>, ...;

INSERT INTO original_table SELECT * FROM temporary_table;

Ponieważ tworzenie tabeli tymczasowej używa TEMPORARYsłowa kluczowego, zostanie ona automatycznie usunięta po zakończeniu sesji (jak sugeruje @ ar34z).

Alex Christodoulou
źródło
7
MySQL obsługuje TEMPORARYsłowo kluczowe do tworzenia tabel tymczasowych. Użycie CREATE TEMPORARY TABLEspowoduje automatyczne upuszczenie tabeli po zakończeniu sesji (serii zapytań SQL). Upuszczenie tabeli nie byłoby konieczne i nie powoduje konfliktu z innymi tabelami tymczasowymi o tej samej nazwie. (np. podczas hakowania na żywo (czego nie poleciłbym))
ar34z
1
ten kod działa tylko wtedy, gdy użytkownik #temporary_table zamiast tabeli tymczasowej, może problem MSSQL?
TruthOf42,
16
Zasadniczo działało to idealnie dla mnie, ale musiałem pokonać ograniczenie Not Null dla klucza podstawowego w tabeli tymczasowej, który wydaje się być kopiowany z oryginalnej tabeli. Naprawiłem to, zmieniając tabelę tymczasową przed aktualizacją w następujący sposób: ALTER TABLE temporary_table MODIFY <auto_inc_not_null_field> INT; Wówczas aktualizacja klucza podstawowego do Null nie zakończy się niepowodzeniem.
snorris,
1
Nie mogę zmusić go do pracy w PostgreSQL 9.4: Exception: null value in column <auto_inc_not_null_field> violates not-null constraint. PróbowałemALTER TABLE temporary_table ALTER COLUMN <auto_inc_not_null_field> DROP NOT NULL;
n1000,
1
Testowałem z różnymi wersjami MySQL i MariaDB. Działa idealnie dla mnie i wolę tę wersję od zaakceptowanej odpowiedzi, co tak naprawdę zdarza się tutaj dość często :)
oprogramowanie hexerei
41

Powiedzmy, że twoja tabela ma dwie inne kolumny: foo i bar

INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, "155"
  FROM Table
 WHERE Event_ID = "120"
Peter Bailey
źródło
4
czy można to zrobić bez konieczności podawania nazw kolumn?
Andrew
@PeterBailey Nowość w MySQL, czy możesz rzucić nieco światła na działanie kodu: /
3kstc
10

Jeśli masz mnóstwo kolumn w tabeli i nie chcesz wpisywać każdej z nich, możesz to zrobić przy użyciu tabeli tymczasowej, takiej jak;

SELECT *
INTO #Temp
FROM Table WHERE Event_ID = "120"
GO

UPDATE #TEMP
SET Column = "Changed"
GO

INSERT INTO Table
SELECT *
FROM #Temp
Davethebfg
źródło
6
uwaga: zakłada się, że nie masz klucza podstawowego w tabeli
kommradHomer
2

Hej, co powiesz na skopiowanie wszystkich pól, zmień jedno z nich na tę samą wartość + coś innego.

INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, Event_ID+"155"
  FROM Table
 WHERE Event_ID = "120"

??????????

Dimitar
źródło
0

Tak długo, jak Event_ID jest liczbą całkowitą, wykonaj następujące czynności:

INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, (Event_ID + 155)
  FROM Table
WHERE Event_ID = "120"
axel.becker
źródło