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.


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.


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

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.


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'));

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;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.