Inserir em ... valores (Seleccionar ... de ...)

estou a tentar {[[0] } uma tabela usando a entrada de outra tabela. Embora isso seja perfeitamente viável para muitos mecanismos de banco de dados, que eu estou sempre a lutar para lembrar a sintaxe correta para a SQL engine do dia (MySQL, Oracle, SQL Server, Informix, e DB2).

existe uma sintaxe de bala de prata proveniente de um padrão SQL (por exemplo, SQL-92 ) que me permitiria inserir os valores sem me preocupar com a base de dados subjacente?

Author: Braiam, 2008-08-25

22 answers

Tenta:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

Este é o padrão ANSI SQL e deve trabalhar em qualquer DBMS

Definitivamente funciona para:
  • Oracle
  • MS SQL Server
  • MySQL
  • Postgres
  • SQLite v3
  • Teradata
  • DB2
  • Sybase
  • Vertica
  • HSQLDB
  • H2
  • AWS RedShift
  • SAP HANA
 1320
Author: Claude Houle, 2017-09-20 09:48:10

@Shadow_x99: isso deve funcionar bem, e você também pode ter várias colunas e outros dados também:

INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT  table2.column1, table2.column2, 8, 'some string etc.'
FROM    table2
WHERE   table2.ID = 7;

Edit: devo mencionar que só usei esta sintaxe com Access, SQL 2000/2005 / Express, MySQL, e PostgreSQL, de modo que estes devem ser cobertos. Um comentarista apontou que vai funcionar com o SQLite3.

 791
Author: travis, 2017-05-23 12:18:24

Para obter apenas um valor num valor múltiplo INSERT de outra tabela i fiz o seguinte em SQLite3:

INSERT INTO column_1 ( val_1, val_from_other_table ) 
VALUES('val_1', (SELECT  val_2 FROM table_2 WHERE val_2 = something))
 85
Author: kylie.a, 2014-06-02 23:55:41

Ambas as respostas que vejo funcionam bem no Informix especificamente, e são basicamente SQL padrão. Ou seja, a notação:

INSERT INTO target_table[(<column-list>)] SELECT ... FROM ...;

Funciona bem com o Informix e, eu esperaria, todos os DBMS. (Uma vez que após 5 ou mais anos atrás, este é o tipo de coisa que o MySQL não suporta sempre; ele agora tem suporte decente para este tipo de padrão de sintaxe de SQL e, AFAIK, ele iria trabalhar em OK nesta notação.) A lista de colunas é opcional, mas indica as colunas-alvo em sequência, de modo que a primeira a coluna do resultado da seleção irá para a primeira coluna listada, etc. Na ausência da lista de colunas, a primeira coluna do resultado da seleção vai para a primeira coluna da tabela de destino.

O que pode ser diferente entre sistemas é a notação usada para identificar tabelas em diferentes bases de dados - a norma não tem nada a dizer sobre operações inter-banco de dados (muito menos inter-DBMS). Com o Informix, pode utilizar a seguinte anotação para identificar um quadro:

[dbase[@server]:][owner.]table

Isto é, você pode especificar um banco de dados, identificando opcionalmente o servidor que hospeda esse banco de dados se não estiver no servidor atual, seguido por um proprietário opcional, dot, e, finalmente, o nome da tabela real. O padrão SQL usa o termo esquema para o que o Informix chama de proprietário. Assim, no Informix, qualquer uma das seguintes anotações poderia identificar uma tabela:

table
"owner".table
dbase:table
dbase:owner.table
dbase@server:table
dbase@server:owner.table

O proprietário em geral não precisa de ser citado; no entanto, se você usar aspas, você precisa obter o nome do dono escrito correctamente-torna-se sensível à capitalização. Ou seja:

someone.table
"someone".table
SOMEONE.table

Todos identifiquem a mesma tabela. Com o Informix, há uma ligeira complicação com as bases de dados do modo ANSI, onde os nomes dos proprietários são geralmente convertidos para maiúsculas (informix é a exceção). Isto é, em um banco de dados de modo ANSI (não comumente usado), você poderia escrever:

CREATE TABLE someone.table ( ... )
E o nome do proprietário no catálogo do sistema seria "alguém", em vez de "alguém". Se incluir o nome do proprietário entre aspas duplas, age como um identificador delimitado. Com SQL padrão, identificadores delimitados podem ser usados em muitos lugares. Com o Informix, você pode usá-los apenas em torno dos nomes dos proprietários -- em outros contextos, o Informix trata tanto as cadeias de caracteres de citação única como de citação dupla como cadeias de caracteres, em vez de separar as cadeias de caracteres de citação simples como cadeias de caracteres e cadeias de citação dupla como identificadores delimitados. (Claro, apenas para completar, há uma variável de ambiente, DELIMIDENT, que pode ser definido para qualquer valor, mas Y é mais seguro - para indicar que as aspas rodeiam sempre os identificadores delimitados e as aspas simples rodeiam sempre as cadeias de caracteres.)

Note que o MS SQL Server consegue usar [identificadores delimitados] entre parêntesis rectos. Parece estranho para mim, e certamente não faz parte do padrão SQL.

 54
Author: Jonathan Leffler, 2008-09-28 03:18:41

A maioria das bases de dados segue a sintaxe básica,

INSERT INTO TABLE_NAME
SELECT COL1, COL2 ...
FROM TABLE_YOU_NEED_TO_TAKE_FROM
;

Todas as bases de dados que usei seguem esta sintaxe:, DB2, SQL Server, MY SQL, PostgresQL

 28
Author: Santhosh, 2013-04-01 10:36:02

Para adicionar algo na primeira resposta, quando queremos apenas poucos registos de outra tabela (neste exemplo apenas um):

INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3, COLUMN4) 
VALUES (value1, value2, 
(SELECT COLUMN_TABLE2 
FROM TABLE2
WHERE COLUMN_TABLE2 like "blabla"),
value4);
 27
Author: Weslor, 2015-05-03 03:33:40

Isto pode ser feito sem especificar as colunas na parte INSERT INTO Se estiver a fornecer valores para todas as colunas na parte SELECT.

Digamos que o quadro 1 tem duas colunas. Esta consulta deve funcionar:
INSERT INTO table1
SELECT  col1, col2
FROM    table2

Isto não funcionaria (O valor para col2 não está especificado):

INSERT INTO table1
SELECT  col1
FROM    table2
Estou a usar o servidor MS SQL. Não sei como funcionam os outros RDMS.
 23
Author: northben, 2012-10-16 14:19:52

Este é outro exemplo usando valores com select:

INSERT INTO table1(desc, id, email) 
SELECT "Hello World", 3, email FROM table2 WHERE ...
 18
Author: Sarvar Nishonboyev, 2014-03-20 09:12:35

Inserção simples quando a sequência da coluna da tabela é conhecida:

    Insert into Table1
    values(1,2,...)

Simples inserção mencionando a coluna:

    Insert into Table1(col2,col4)
    values(1,2)

Inserção a granel quando o número de colunas seleccionadas de uma tabela (#table2) é igual à tabela de inserção (Table1)

    Insert into Table1 {Column sequence}
    Select * -- column sequence should be same.
       from #table2

Inserção a granel quando quiser inserir apenas na coluna desejada de uma tabela (quadro 1):

    Insert into Table1 (Column1,Column2 ....Desired Column from Table1)  
    Select Column1,Column2..desired column from #table2
       from #table2
 17
Author: RameezAli, 2016-01-19 23:50:31

Em vez de VALUES parte de INSERT consulta, basta usar SELECT consulta como abaixo.

INSERT INTO table1 ( column1 , 2, 3... )
SELECT col1, 2, 3... FROM table2
 13
Author: logan, 2018-08-13 00:14:03

Aqui está como inserir a partir de várias tabelas. Este exemplo em particular é onde você tem uma tabela de mapeamento em muitos ou muitos cenários:

insert into StudentCourseMap (StudentId, CourseId) 
SELECT  Student.Id, Course.Id FROM Student, Course 
WHERE Student.Name = 'Paddy Murphy' AND Course.Name = 'Basket weaving for beginners'
(Sei que a correspondência com o nome do aluno pode devolver mais do que um valor, mas já percebeste a ideia. A correspondência em algo diferente de um Id é necessária quando o Id é uma coluna de identidade e é Desconhecido.)
 12
Author: Ciaran Bruen, 2016-03-23 16:34:55

Aqui está outro exemplo em que a fonte é tomada usando mais do que uma tabela:

INSERT INTO cesc_pf_stmt_ext_wrk( 
  PF_EMP_CODE    ,
  PF_DEPT_CODE   ,
  PF_SEC_CODE    ,
  PF_PROL_NO     ,
  PF_FM_SEQ      ,
  PF_SEQ_NO      ,
  PF_SEP_TAG     ,
  PF_SOURCE) 
SELECT
  PFl_EMP_CODE    ,
  PFl_DEPT_CODE   ,
  PFl_SEC         ,
  PFl_PROL_NO     ,
  PF_FM_SEQ       ,
  PF_SEQ_NO       ,
  PFl_SEP_TAG     ,
  PF_SOURCE
 FROM cesc_pf_stmt_ext,
      cesc_pfl_emp_master
 WHERE pfl_sep_tag LIKE '0'
   AND pfl_emp_code=pf_emp_code(+);

COMMIT;
 11
Author: SWATI BISWAS, 2013-03-22 16:28:53
INSERT INTO yourtable
SELECT fielda, fieldb, fieldc
FROM donortable;

Isto funciona em todos os DBMS

 11
Author: Matt, 2015-05-20 08:44:14
Isto funcionou comigo.
insert into table1 select * from table2
A frase é um pouco diferente da Do Oráculo.
 10
Author: elijah7, 2013-11-20 12:43:41

Para o servidor SQL da Microsoft, recomendarei aprender a interpretar a sintaxe fornecida no MSDN. Com o Google é mais fácil do que nunca, procurar sintaxe.

Para este caso em particular, tente

Google: inserir site:microsoft.com

O primeiro resultado será http://msdn.microsoft.com/en-us/library/ms174335.aspx

Descer para o exemplo ("usando as opções seleccionar e executar para inserir dados de outras tabelas") se o encontrar difícil de interpretar a sintaxe dada no topo da página.

[ WITH <common_table_expression> [ ,...n ] ]
INSERT 
{
        [ TOP ( expression ) [ PERCENT ] ] 
        [ INTO ] 
        { <object> | rowset_function_limited 
          [ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
        }
    {
        [ ( column_list ) ] 
        [ <OUTPUT Clause> ]
        { VALUES ( { DEFAULT | NULL | expression } [ ,...n ] ) [ ,...n     ] 
        | derived_table       <<<<------- Look here ------------------------
        | execute_statement   <<<<------- Look here ------------------------
        | <dml_table_source>  <<<<------- Look here ------------------------
        | DEFAULT VALUES 
        }
    }
}
[;]

Isto deve ser aplicável a quaisquer outros RDBMS aí disponíveis. Não vale a pena recordar toda a sintaxe para todos os produtos IMO.

 10
Author: Faiz, 2015-03-11 07:54:17

Pode tentar isto se quiser inserir toda a coluna usando a tabela SELECT * INTO.

SELECT  *
INTO    Table2
FROM    Table1;
 10
Author: Bharath theorare, 2016-06-17 10:28:45

Na verdade prefiro o seguinte no SQL Server 2008:

SELECT Table1.Column1, Table1.Column2, Table2.Column1, Table2.Column2, 'Some String' AS SomeString, 8 AS SomeInt
INTO Table3
FROM Table1 INNER JOIN Table2 ON Table1.Column1 = Table2.Column3

Ele elimina o passo de adicionar o conjunto Insert (), e você apenas seleciona os valores que vão na tabela.

 9
Author: Grungondola, 2013-03-22 14:57:06
select *
into tmp
from orders

Parece bom, mas só funciona se o tmp não existir (cria-o e preenche). (SQL sever)

Para inserir na tabela tmp existente:

set identity_insert tmp on

insert tmp 
([OrderID]
      ,[CustomerID]
      ,[EmployeeID]
      ,[OrderDate]
      ,[RequiredDate]
      ,[ShippedDate]
      ,[ShipVia]
      ,[Freight]
      ,[ShipName]
      ,[ShipAddress]
      ,[ShipCity]
      ,[ShipRegion]
      ,[ShipPostalCode]
      ,[ShipCountry] )
      select * from orders

set identity_insert tmp off
 7
Author: Pavel, 2014-05-18 13:36:12

A melhor maneira de inserir vários registos de quaisquer outras tabelas.

INSERT  INTO dbo.Users
            ( UserID ,
              Full_Name ,
              Login_Name ,
              Password
            )
            SELECT  UserID ,
                    Full_Name ,
                    Login_Name ,
                    Password
            FROM    Users_Table
            (INNER JOIN / LEFT JOIN ...)
            (WHERE CONDITION...)
            (OTHER CLAUSE)
 5
Author: Manish Vadher, 2018-06-07 06:59:35

Basta usar parêntesis para seleccionar cláusula em Inserir. Por exemplo:

INSERT INTO Table1 (col1, col2, your_desired_value_from_select_clause, col3)
VALUES (
   'col1_value', 
   'col2_value',
   (SELECT col_Table2 FROM Table2 WHERE IdTable2 = 'your_satisfied_value_for_col_Table2_selected'),
   'col3_value'
);
 2
Author: Dasikely, 2018-09-24 09:25:16

Se escolher a rota de inserção de valores para inserir várias linhas, certifique-se de delimitar os valores em conjuntos usando parêntesis, por isso:

INSERT INTO `receiving_table`
  (id,
  first_name,
  last_name)
VALUES 
  (1002,'Charles','Babbage'),
  (1003,'George', 'Boole'),
  (1001,'Donald','Chamberlin'),
  (1004,'Alan','Turing'),
  (1005,'My','Widenius');

Caso contrário, os objectos MySQL que "a contagem de colunas não corresponde à contagem de valores na linha 1", e você acaba por escrever um post trivial quando finalmente descobre o que fazer sobre isso.

 0
Author: Sebastian, 2017-06-09 03:51:51
INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT  COLUMN_NAME
FROM    ANOTHER_TABLE_NAME 
WHERE CONDITION;
 0
Author: Gaurav, 2018-08-13 00:14:28