Insertar en ... valores (SELECT ... FROM ...)

estoy tratando de INSERT INTO una tabla usando la entrada de otra tabla. Aunque esto es completamente factible para muchos motores de base de datos, siempre parece que me cuesta recordar la sintaxis correcta para el SQL motor del díaMySQL, Oracle, SQL Server, Informix y DB2).

¿Existe una sintaxis mágica procedente de un estándar SQL (por ejemplo, SQL-92) que me permitiría insertar los valores sin preocuparme por la base de datos subyacente?

preguntado el 25 de agosto de 08 a las 10:08

este ejemplo funciona: insert into tag_zone select @ tag, zoneid, GETDATE (), @ positiong.STIntersects (polygon) from zone -

26 Respuestas

Tratar:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

Este es ANSI SQL estándar y debería funcionar en cualquier DBMS

Definitivamente funciona para:

  • Oracle
  • MS SQL Server
  • MySQL
  • Postgres
  • SQLite v3
  • Teradata
  • DB2
  • Sybase
  • vertical
  • HSQLDB
  • H2
  • RedShift de AWS
  • SAP HANA
  • Google Spanner

Respondido 17 Feb 21, 16:02

La respuesta de Claude Houle: debería funcionar bien, y también puede tener varias columnas y otros datos:

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

Solo he usado esta sintaxis con Access, SQL 2000/2005 / Express, MySQL y PostgreSQL, por lo que deberían estar cubiertos. También debería funcionar con SQLite3.

Respondido 18 Feb 20, 20:02

¿Qué pasa si la condición where cambia a table2.country y devuelve un número de filas mayor que uno? Tengo un problema similar aquí: stackoverflow.com/questions/36030370/… - vijayrana

No debería haber ningún problema al insertar más de una fila. - rinukkusu

¿Es necesario que insertemos en todas las columnas de la tabla? maheshmnj

@maheshmnj no, solo las columnas que están configuradas como NOT NULL y no es necesario incluir ningún valor predeterminado, cualquier otra columna se configurará con sus valores predeterminados o NULL - travis

Para obtener solo un valor en un valor múltiple INSERT de otra tabla hice lo siguiente en SQLite3:

INSERT INTO column_1 ( val_1, val_from_other_table ) 
VALUES('val_1', (SELECT  val_2 FROM table_2 WHERE val_2 = something))

Respondido el 03 de junio de 14 a las 00:06

Solo para aclarar: esto es incorrecto para SQLite3. Según la documentación, los datos de origen del INSERT is ya sea VALUES o un SELECT declaración, no ambas. - usuario909694

Es cierto que la documentación no lo incluye, pero funciona. Independientemente, creo que usar la declaración de selección en lugar de valores lo hace más legible. - banjocat

Funciona para especificar un valor dentro de una fila, pero el caso más general requiere obtener muchas filas. - Luchosteína

Si val_1 no cambia en las filas, ¿entonces la siguiente sintaxis podría funcionar en SQLite3? seleccione 'foo', some_column de some_table - funciona en SQLServer 2014 - Chris B

La documentación enumera esto (¿ahora?): Esta sintaxis es INSERT INTO ... VALUES ([expr], [expr], ...) y uno de los caminos en [expr] is {{NOT} EXISTS} ([select-stmt]) - tenga en cuenta que se requieren las paréntesis alrededor de la declaración de selección ({} que significa opcional) - zapl

Las dos respuestas que veo funcionan bien en Informix específicamente, y son básicamente SQL estándar. Es decir, la notación:

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

funciona bien con Informix y, supongo, con todo el DBMS. (Hace 5 años o más, este es el tipo de cosas que MySQL no siempre admitía; ahora tiene un soporte decente para este tipo de sintaxis SQL estándar y, AFAIK, funcionaría bien en esta notación). es opcional pero indica las columnas de destino en secuencia, por lo que la primera columna del resultado de SELECT irá a la primera columna listada, etc. En ausencia de la lista de columnas, la primera columna del resultado de SELECT irá a la primera columna de la tabla de destino.

Lo que puede ser diferente entre sistemas es la notación utilizada para identificar tablas en diferentes bases de datos; el estándar no tiene nada que decir sobre las operaciones entre bases de datos (y mucho menos entre DBMS). Con Informix, puede utilizar la siguiente notación para identificar una tabla:

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

Es decir, puede especificar una base de datos, identificando opcionalmente el servidor que aloja esa base de datos si no está en el servidor actual, seguido de un propietario opcional, un punto y finalmente el nombre real de la tabla. El estándar SQL usa el término esquema para lo que Informix llama propietario. Por lo tanto, en Informix, cualquiera de las siguientes notaciones podría identificar una tabla:

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

El propietario en general no necesita cotización; sin embargo, si usa comillas, debe escribir correctamente el nombre del propietario; se distingue entre mayúsculas y minúsculas. Es decir:

someone.table
"someone".table
SOMEONE.table

todos identifican la misma mesa. Con Informix, existe una leve complicación con las bases de datos MODE ANSI, donde los nombres de los propietarios generalmente se convierten a mayúsculas (informix es la excepción). Es decir, en una base de datos MODE ANSI (no se usa comúnmente), podría escribir:

CREATE TABLE someone.table ( ... )

y el nombre del propietario en el catálogo del sistema sería "ALGUIEN", en lugar de "alguien". Si incluye el nombre del propietario entre comillas dobles, actúa como un identificador delimitado. Con SQL estándar, los identificadores delimitados se pueden utilizar en muchos lugares. Con Informix, puede usarlos solo alrededor de nombres de propietario; en otros contextos, Informix trata las cadenas entre comillas simples y dobles como cadenas, en lugar de separar las cadenas entre comillas simples como cadenas y las cadenas entre comillas dobles como identificadores delimitados. (Por supuesto, solo para completar, hay una variable de entorno, DELIMIDENT, que se puede establecer, en cualquier valor, pero Y es más seguro, para indicar que las comillas dobles siempre rodean los identificadores delimitados y las comillas simples siempre rodean las cadenas).

Tenga en cuenta que MS SQL Server se las arregla para utilizar [identificadores delimitados] encerrados entre corchetes. Me parece extraño y ciertamente no es parte del estándar SQL.

Respondido el 28 de Septiembre de 08 a las 04:09

Para agregar algo en la primera respuesta, cuando queremos solo unos pocos registros de otra tabla (en este ejemplo, solo uno):

INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3, COLUMN4) 
VALUES (value1, value2, 
(SELECT COLUMN_TABLE2 
FROM TABLE2
WHERE COLUMN_TABLE2 like "blabla"),
value4);

contestado el 03 de mayo de 15 a las 04:05

Este enfoque solo se aplica a las subconsultas en las que solo se selecciona una columna. En el caso de una subconsulta de varias columnas, se generará un error 'la subconsulta debe devolver solo una columna'. Adopte la respuesta de @travis entonces. - zorro de nieve

Dos enfoques para insertar en una subconsulta selecta.

  1. Con la subconsulta SELECT devolviendo resultados con Una fila.
  2. Con la subconsulta SELECT devolviendo resultados con Filas múltiples.

1. Enfoque para la subconsulta With SELECT que devuelve resultados con una fila.

INSERT INTO <table_name> (<field1>, <field2>, <field3>) 
VALUES ('DUMMY1', (SELECT <field> FROM <table_name> ),'DUMMY2');

En este caso, se supone que SELECT Subconsulta devuelve solo una fila de resultado según la condición WHERE o funciones agregadas de SQL como SUM, MAX, AVG, etc. De lo contrario, arrojará un error

2. Enfoque para la subconsulta With SELECT que devuelve resultados con varias filas.

INSERT INTO <table_name> (<field1>, <field2>, <field3>) 
SELECT 'DUMMY1', <field>, 'DUMMY2' FROM <table_name>;

El segundo enfoque funcionará para ambos casos.

Respondido 04 Abr '19, 05:04

En lugar de VALUES parte de INSERT consulta, solo usa SELECT consulta como se muestra a continuación.

INSERT INTO table1 ( column1 , 2, 3... )
SELECT col1, 2, 3... FROM table2

Respondido 13 ago 18, 01:08

La mayoría de las bases de datos siguen la sintaxis básica,

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

Cada base de datos que he usado sigue esta sintaxis, a saber, DB2, SQL Server, MY SQL, PostgresQL

Respondido 01 Abr '13, 11:04

Esto se puede hacer sin especificar las columnas en el INSERT INTO parte si está proporcionando valores para todas las columnas en el SELECT parte.

Digamos que la tabla1 tiene dos columnas. Esta consulta debería funcionar:

INSERT INTO table1
SELECT  col1, col2
FROM    table2

Esto NO funcionaría (valor para col2 no se especifica):

INSERT INTO table1
SELECT  col1
FROM    table2

Estoy usando MS SQL Server. No sé cómo funcionan otros RDMS.

Respondido 16 Oct 12, 15:10

Este es otro ejemplo que usa valores con seleccionar:

INSERT INTO table1(desc, id, email) 
SELECT "Hello World", 3, email FROM table2 WHERE ...

respondido 20 mar '14, 09:03

Respuesta antigua y aún útil. Bastante simple y obvio, pero cubre exactamente mis necesidades. ¡Gracias! - Sebastián Kaczmarek

Inserción simple cuando se conoce la secuencia de columnas de la tabla:

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

Columna de mención de inserción simple:

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

Inserción masiva cuando el número de columnas seleccionadas de una tabla (# table2) es igual a la tabla de inserción (Table1)

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

Inserción masiva cuando desea insertar solo en la columna deseada de una tabla (tabla1):

    Insert into Table1 (Column1,Column2 ....Desired Column from Table1)  
    Select Column1,Column2..desired column from #table2
       from #table2

Respondido el 19 de enero de 16 a las 23:01

Solo usa paréntesis para SELECCIONAR cláusula en INSERT. Por ejemplo así:

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

Respondido el 24 de Septiembre de 18 a las 10:09

Aquí hay otro ejemplo en el que la fuente se toma utilizando más de una tabla:

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;

respondido 22 mar '13, 16:03

A continuación, se explica cómo insertar desde varias tablas. Este ejemplo particular es donde tiene una tabla de mapeo en un escenario de muchos a muchos:

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'

(Me doy cuenta de que la coincidencia en el nombre del estudiante puede devolver más de un valor, pero se hace una idea. La coincidencia en algo que no sea una identificación es necesaria cuando la identificación es una columna de identidad y se desconoce).

respondido 23 mar '16, 16:03

INSERT INTO yourtable
SELECT fielda, fieldb, fieldc
FROM donortable;

Esto funciona en todos los DBMS

contestado el 20 de mayo de 15 a las 09:05

Puede probar esto si desea insertar todas las columnas usando SELECT * INTO mesa.

SELECT  *
INTO    Table2
FROM    Table1;

Respondido el 17 de junio de 16 a las 11:06

De hecho, prefiero lo siguiente en 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

Elimina el paso de agregar el conjunto Insert (), y solo selecciona qué valores van en la tabla.

respondido 22 mar '13, 14:03

Esto funcionó para mí:

insert into table1 select * from table2

La oración es un poco diferente a la de Oracle.

respondido 20 nov., 13:12

Para Microsoft SQL Server, recomendaré aprender a interpretar SYNTAX proporcionado en MSDN. Con Google es más fácil que nunca buscar la sintaxis.

Para este caso particular, intente

Google: insertar sitio: microsoft.com

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

desplácese hacia abajo hasta el ejemplo ("Uso de las opciones SELECT y EXECUTE para insertar datos de otras tablas") si le resulta difícil interpretar la sintaxis dada en la parte superior de la 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 
        }
    }
}
[;]

Esto debería ser aplicable a cualquier otro RDBMS disponible allí. No tiene sentido recordar toda la sintaxis de todos los productos, en mi opinión.

respondido 11 mar '15, 07:03

Estoy completamente en desacuerdo, he estado mirando esas declaraciones de sintaxis durante años y todavía no puedo encontrar ni cara ni cruz con ellas. Los ejemplos son mucho más útiles: reggaeguitarra

Esta no es una respuesta, dice "lee los documentos" y eso es todo. reggaeguitarra

INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT  COLUMN_NAME
FROM    ANOTHER_TABLE_NAME 
WHERE CONDITION;

Respondido 13 ago 18, 01:08

@ggorlen Me parece bastante evidente. reggaeguitarra

Se marcó en la cola de revisión como una respuesta de solo código. Sin embargo, puedo ver su punto aquí: no hay mucho que decir en el contexto de la mayoría de las respuestas en esta página ahora que lo veo en su entorno natural. - ggorlen

La mejor forma de insertar varios registros de otras tablas.

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)

Respondido el 07 de junio de 18 a las 07:06

select *
into tmp
from orders

Se ve bien, pero funciona solo si tmp no existe (lo crea y lo llena). (Servidor SQL)

Para insertar en una tabla 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

contestado el 18 de mayo de 14 a las 14:05

SI desea insertar algunos datos en una tabla sin querer escribir el nombre de la columna.

INSERT INTO CUSTOMER_INFO
   (SELECT CUSTOMER_NAME,
           MOBILE_NO,
           ADDRESS
      FROM OWNER_INFO cm)

Dónde están las mesas:

            CUSTOMER_INFO               ||            OWNER_INFO
----------------------------------------||-------------------------------------
CUSTOMER_NAME | MOBILE_NO | ADDRESS     || CUSTOMER_NAME | MOBILE_NO | ADDRESS 
--------------|-----------|---------    || --------------|-----------|--------- 
      A       |     +1    |   DC        ||       B       |     +55   |   RR  

Resultado:

            CUSTOMER_INFO               ||            OWNER_INFO
----------------------------------------||-------------------------------------
CUSTOMER_NAME | MOBILE_NO | ADDRESS     || CUSTOMER_NAME | MOBILE_NO | ADDRESS 
--------------|-----------|---------    || --------------|-----------|--------- 
      A       |     +1    |   DC        ||       B       |     +55   |   RR
      B       |     +55   |   RR        ||

Respondido el 14 de junio de 20 a las 22:06

Si sigue la ruta INSERT VALUES para insertar varias filas, asegúrese de delimitar los VALORES en conjuntos usando paréntesis, así:

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

De lo contrario, los objetos MySQL que "el recuento de columnas no coincide con el recuento de valores en la fila 1", y terminas escribiendo una publicación trivial cuando finalmente descubres qué hacer al respecto.

Respondido el 09 de junio de 17 a las 04:06

La pregunta es "insertar en una tabla usando la entrada de otra mesa". ¿Cómo responde su respuesta a esta pregunta? - Catalizador de calidad

Eh, no seas demasiado duro con él. Respondió a mi pregunta cuando estaba buscando en Google. @QualityCatalyst - Darth Citus

En informix funciona como dijo Claude:

INSERT INTO table (column1, column2) 
VALUES (value1, value2);    

Respondido el 12 de diciembre de 19 a las 07:12

Postgres admite lo siguiente: crear la tabla company.monitor2 como seleccionar * de company.monitor;

Respondido 01 Abr '20, 14:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.