sql - una - Insertar en... valores(SELECCIONAR... DESDE...)
insertar una consulta en una tabla sql (22)
@ Shadow_x99 : Eso debería funcionar bien, y también puede tener varias columnas y otros datos también:
INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT table2.column1, table2.column2, 8, ''some string etc.''
FROM table2
WHERE table2.ID = 7;
Edición: Debo mencionar que solo he usado esta sintaxis con Access, SQL 2000/2005 / Express, MySQL y PostgreSQL, por lo que deberían estar cubiertos. Un comentarista ha señalado que funcionará con SQLite3.
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 me cuesta trabajo recordar la sintaxis correcta para el motor SQL
del día ( MySQL , Oracle , SQL Server , Informix y DB2 ).
¿Existe una sintaxis de viñeta de plata proveniente de un estándar de SQL (por ejemplo, SQL-92 ) que me permita insertar los valores sin preocuparme por la base de datos subyacente?
Aquí es cómo insertar desde varias tablas. Este ejemplo en particular es donde tiene una tabla de asignación 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 hacer coincidir el nombre del estudiante puede devolver más de un valor, pero se entiende la idea. La coincidencia en algo que no sea un Id. Es necesario cuando el Id es una columna de identidad y es desconocido).
Aquí hay otro ejemplo donde se toma la fuente usando 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;
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.
En lugar de la parte de VALUES
de la consulta INSERT
, simplemente use la consulta SELECT
como se muestra a continuación.
INSERT INTO table1 ( column1 , 2, 3... )
SELECT col1, 2, 3... FROM table2
Este es otro ejemplo usando valores con select:
INSERT INTO table1(desc, id, email)
SELECT "Hello World", 3, email FROM table2 WHERE ...
Esto funcionó para mí:
insert into table1 select * from table2
La oración es un poco diferente de la de Oracle.
Esto se puede hacer sin especificar las columnas en la parte INSERT INTO
si está suministrando valores para todas las columnas en la parte SELECT
.
Digamos que la tabla 1 tiene dos columnas. Esta consulta debería funcionar:
INSERT INTO table1
SELECT col1, col2
FROM table2
Esto NO col2
(no se especifica el valor para col2
):
INSERT INTO table1
SELECT col1
FROM table2
Estoy usando MS SQL Server. No sé cómo funcionan otros RDMS.
Inserción simple cuando se conoce la secuencia de la columna de la tabla:
Insert into Table1
values(1,2,...)
Colocación simple mencionando la columna:
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 (tabla 1):
Insert into Table1 (Column1,Column2 ....Desired Column from Table1)
Select Column1,Column2..desired column from #table2
from #table2
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
;
Todas las bases de datos que he usado siguen esta sintaxis, a saber, DB2
, SQL Server
, MY SQL
, PostgresQL
La mejor manera de insertar múltiples registros de cualquier otra tabla.
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)
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, espero, todos los DBMS. (Una vez hace 5 o más años, este es el tipo de cosas que MySQL no siempre admitió; ahora tiene un soporte decente para este tipo de sintaxis SQL estándar y, AFAIK, funcionaría bien en esta notación). La lista de columnas 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 de la lista, etc. En ausencia de la lista de columnas, la primera columna del resultado de SELECT entra en la columna Primera columna de la tabla de destino.
Lo que puede ser diferente entre los sistemas es la notación utilizada para identificar tablas en diferentes bases de datos: el estándar no tiene nada que decir acerca de las operaciones entre bases de datos (y mucho menos entre las bases de datos DBMS). Con Informix, puede usar 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 hospeda esa base de datos si no está en el servidor actual, seguido de un propietario opcional, un punto y, finalmente, el nombre de la tabla real. El estándar SQL usa el término esquema para lo que Informix llama el propietario. Así, 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 ser citado; sin embargo, si utiliza comillas, debe escribir correctamente el nombre del propietario, ya que se distingue entre mayúsculas y minúsculas. Es decir:
someone.table
"someone".table
SOMEONE.table
Todos identifican la misma tabla. 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 encierra 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 los nombres de los propietarios; 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, DELIMIDENTE, que puede configurarse, en cualquier valor, pero Y es la más segura, 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 usar [identificadores delimitados] encerrados entre corchetes. Me parece extraño, y ciertamente no es parte del estándar SQL.
Para Microsoft SQL Server, recomendaré aprender a interpretar el SYNTAX proporcionado en MSDN. Con Google es más fácil que nunca, buscar 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 ("Usar las opciones SELECCIONAR y EJECUTAR para ejecutar 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 para cualquier otro RDBMS disponible allí. No tiene sentido recordar toda la sintaxis de todos los productos IMO.
Para agregar algo en la primera respuesta, cuando queremos solo algunos 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);
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))
Puede intentar esto si desea insertar todas las columnas utilizando la tabla SELECT * INTO
.
SELECT *
INTO Table2
FROM Table1;
Si va a la ruta INSERTAR VALORES para insertar varias filas, asegúrese de delimitar los VALORES en conjuntos utilizando paréntesis, por lo que:
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 de MySQL que "el recuento de columnas no coincide con el valor del recuento en la fila 1", terminan escribiendo una publicación trivial cuando finalmente descubren qué hacer al respecto.
Simplemente use paréntesis para la cláusula SELECT en INSERT. Por ejemplo como este:
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''
);
Tratar:
INSERT INTO table1 ( column1 )
SELECT col1
FROM table2
Esto es ANSI SQL estándar y debería funcionar en cualquier DBMS
Definitivamente funciona para:
- Oráculo
- MS SQL Server
- MySQL
- Postgres
- SQLite v3
- Teradata
- DB2
- Sybase
- Vertica
- HSQLDB
- H2
- AWS RedShift
- SAP HANA
INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT COLUMN_NAME
FROM ANOTHER_TABLE_NAME
WHERE CONDITION;
INSERT INTO yourtable
SELECT fielda, fieldb, fieldc
FROM donortable;
Esto funciona en todos los DBMS
select *
into tmp
from orders
Se ve bien, pero funciona solo si tmp no existe (lo crea y se llena). (Servidor SQL)
Para insertar en la 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