INSERIR EM… SELECIONE para todas as colunas do MySQL

119

Estou tentando mover dados antigos de:

this_table >> this_table_archive

copiando todas as colunas. Eu tentei isso, mas não funciona:

INSERT INTO this_table_archive (*) VALUES (SELECT * FROM this_table WHERE entry_date < '2011-01-01 00:00:00');

Nota: as tabelas são idênticas e foram iddefinidas como chave primária.

Kyle
fonte
1
Defina "não funciona". Estou tendo um problema semelhante, mas não sei dizer porque você não disse qual era o seu problema!
Lightness Races in Orbit
Não está quebrado, simplesmente não funciona.
Webmaster G

Respostas:

218

A sintaxe correta é descrita no manual . Tente o seguinte:

INSERT INTO this_table_archive (col1, col2, ..., coln)
SELECT col1, col2, ..., coln
FROM this_table
WHERE entry_date < '2011-01-01 00:00:00';

Se as colunas de identificação forem uma coluna de incremento automático e você já tiver alguns dados nas duas tabelas, em alguns casos, poderá omitir o ID da lista de colunas e gerar novos IDs para evitar inserir um ID que já exista no original tabela. Se sua tabela de destino estiver vazia, isso não será um problema.

Mark Byers
fonte
73

Para a sintaxe, parece com isso (deixe a lista de colunas para implicitamente significar "todos")

INSERT INTO this_table_archive
SELECT *
FROM this_table
WHERE entry_date < '2011-01-01 00:00:00'

Para evitar erros de chave primária, se você já possui dados na tabela de arquivamento

INSERT INTO this_table_archive
SELECT t.*
FROM this_table t
LEFT JOIN this_table_archive a on a.id=t.id
WHERE t.entry_date < '2011-01-01 00:00:00'
  AND a.id is null  # does not yet exist in archive
RichardTheKiwi
fonte
6
+1 na junção esquerda para evitar colisões com a chave primária.
Hartley Brody
23

Além da resposta de Mark Byers:

Às vezes, você também deseja inserir detalhes codificados permanentemente; caso contrário, pode haver uma falha de restrição exclusiva, etc.

INSERT INTO matrimony_domain_details (domain, type, logo_path)
SELECT 'www.example.com', type, logo_path
FROM matrimony_domain_details
WHERE id = 367

Aqui, o valor do domínio é adicionado por mim da maneira codificada para se livrar da restrição Exclusiva.

Pratik
fonte
4

você não precisa de double () para o bit de valores? se não, tente isso (embora deva haver uma maneira melhor

insert into this_table_archive (id, field_1, field_2, field_3) 
values
((select id from this_table where entry_date < '2001-01-01'), 
((select field_1 from this_table where entry_date < '2001-01-01'), 
((select field_2 from this_table where entry_date < '2001-01-01'), 
((select field_3 from this_table where entry_date < '2001-01-01'));
Daniel Casserly
fonte
2
O OP está usando INSERT INTO .. SELECT FROM, não INSERT INTO .. VALUES. Recurso diferente.
Lightness Races in Orbit
0

Mais exemplos e detalhes

    INSERT INTO vendors (
     name, 
     phone, 
     addressLine1,
     addressLine2,
     city,
     state,
     postalCode,
     country,
     customer_id
 )
 SELECT 
     name,
     phone,
     addressLine1,
     addressLine2,
     city,
     state ,
     postalCode,
     country,
     customer_id
 FROM 
     customers;
Desenvolvedor
fonte