MySQL: Como copiar linhas, mas alterar alguns campos?

195

Eu tenho um grande número de linhas que gostaria de copiar, mas preciso alterar um campo.

Posso selecionar as linhas que quero copiar:

select * from Table where Event_ID = "120"

Agora eu quero copiar todas essas linhas e criar novas linhas enquanto configura o Event_IDpara 155. Como posso fazer isso?

Andrew
fonte

Respostas:

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

Aqui, o col2, ... representa as colunas restantes (as que não são Event_ID) na sua tabela.

dcp
fonte
39
existe alguma maneira de fazer isso sem precisar especificar os nomes das colunas?
Andrew
4
Não que eu saiba. Obviamente, se sua tabela tiver 1000 colunas ou algo assim e você não quiser digitar todas elas, poderá escrever uma instrução SQL para criar sua instrução SQL :). A maneira como você faria isso seria usar o information_schema para obter os nomes das colunas da tabela. Mas isso é realmente um exagero, basta digitar os nomes das colunas.
Dcp
3
Isso seria possível usando um asterisco para obter as colunas restantes?
Peter
2
Conectado ao voto positivo apenas para descobrir que já o tenho votado. Eu acho que isso me salvou várias vezes agora :) Obrigado!
aexl
2
@Bitterblue - Desculpe, eu não entendo o seu comentário. Eu nunca disse col2, ... eram colunas que você não deseja copiar, apenas disse que elas representam as colunas restantes da tabela. É óbvio que eles serão copiados, caso contrário, eles não estariam na instrução SQL.
dcp 6/03
140

Esta é uma solução em que você tem muitos campos em sua tabela e não deseja que a cãibra ocorra ao digitar todos os campos, basta digitar os necessários :)

Como copiar algumas linhas na mesma tabela, com alguns campos com valores diferentes:

  1. Crie uma tabela temporária com todas as linhas que você deseja copiar
  2. Atualize todas as linhas da tabela temporária com os valores desejados
  3. Se você tiver um campo de incremento automático, defina-o como NULL na tabela temporária
  4. Copie todas as linhas da tabela temporária para sua tabela original
  5. Excluir a tabela temporária

Seu código:

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

Código geral do cenário:

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

Código simplificado / condensado:

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;

Como a criação da tabela temporária usa a TEMPORARYpalavra-chave, ela será descartada automaticamente quando a sessão terminar (como @ ar34z sugeriu).

Alex Christodoulou
fonte
7
O MySQL suporta a TEMPORARYpalavra-chave para criar tabelas temporárias. O uso de CREATE TEMPORARY TABLEeliminará automaticamente a tabela quando a sessão (uma série de consultas SQL) for concluída. Soltar a tabela não seria necessário e não entra em conflito com outras tabelas temporárias usando o mesmo nome. (por exemplo, quando a pirataria ao vivo (que eu não recomendo))
ar34z
1
esse código funciona apenas se você usar #temporary_table em vez de temporary_table, talvez seja um problema do MSSQL?
TruthOf42
16
Isso basicamente funcionou perfeitamente para mim, mas eu tive que superar uma restrição Não Nulo na chave primária na tabela temporária que parece ser copiada da tabela original. Corrigi isso alterando a tabela temporária antes da atualização da seguinte maneira: A ALTER TABLE temporary_table MODIFY <auto_inc_not_null_field> INT; atualização da chave primária para Null não falharia.
snorris
1
Eu não posso fazê-lo funcionar no PostgreSQL 9.4: Exception: null value in column <auto_inc_not_null_field> violates not-null constraint. Eu tenteiALTER TABLE temporary_table ALTER COLUMN <auto_inc_not_null_field> DROP NOT NULL;
n1000
1
Eu testei com diferentes versões do MySQL e MariaDB. Funciona perfeito para mim e eu prefiro esta versão para a resposta aceita, o que realmente acontece muitas vezes aqui :)
software hexerei
40

Digamos que sua mesa tenha duas outras colunas: foo e bar

INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, "155"
  FROM Table
 WHERE Event_ID = "120"
Peter Bailey
fonte
4
existe alguma maneira de fazer isso sem precisar especificar os nomes das colunas?
Andrew
@PeterBailey Novo no MySQL, você poderia esclarecer como o código funciona: /
3kstc 5/16
10

Se você tem um monte de colunas em sua tabela e não deseja digitar cada uma delas, pode fazê-lo usando uma tabela temporária, como;

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

UPDATE #TEMP
SET Column = "Changed"
GO

INSERT INTO Table
SELECT *
FROM #Temp
Davethebfg
fonte
6
uma nota: isso pressupõe que você não tem chave primária na sua mesa
kommradHomer
2

Ei, que tal copiar todos os campos, alterar um deles para o mesmo valor + outra coisa.

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

??????????

Dimitar
fonte
0

Enquanto Event_ID for Inteiro, faça o seguinte:

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