Inserisci in ... valori (SELEZIONA ... DA ...)


1427

Sto provando a INSERT INTOun tavolo usando l'input da un altro tavolo. Sebbene ciò sia del tutto fattibile per molti motori di database, mi sembra sempre difficile ricordare la sintassi corretta per il SQLmotore del giorno ( MySQL , Oracle , SQL Server , Informix e DB2 ).

Esiste una sintassi del proiettile d'argento proveniente da uno standard SQL (ad esempio, SQL-92 ) che mi consentirebbe di inserire i valori senza preoccuparmi del database sottostante?


1
questo esempio funziona: inserisci in tag_zone select @ tag, zoneid, GETDATE (), @ positiong.STIntersects (poligono) dalla zona
Uğur Gümüşhan

Risposte:


1611

Provare:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

Questo è standard ANSI SQL e dovrebbe funzionare su qualsiasi DBMS

Funziona sicuramente per:

  • Oracolo
  • MS SQL Server
  • MySQL
  • Postgres
  • SQLite v3
  • Teradata
  • DB2
  • Sybase
  • Vertica
  • HSQLDB
  • H2
  • AWS RedShift
  • SAP HANA

947

La risposta di Claude Houle : dovrebbe funzionare bene e puoi anche avere più colonne e altri dati:

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

Ho usato questa sintassi solo con Access, SQL 2000/2005 / Express, MySQL e PostgreSQL, quindi quelli dovrebbero essere coperti. Dovrebbe funzionare anche con SQLite3.


1
cosa succede se, la condizione in cui è cambiata in table2.country e restituisce un numero di righe maggiore di una? Ho avuto problema simile qui: stackoverflow.com/questions/36030370/...
vijayrana

1
Non ci dovrebbero essere problemi con l'inserimento di più di una riga.
rinukkusu,

è necessario che inseriamo in tutte le colonne della tabella
maheshmnj

1
@maheshmnj no, solo le colonne impostate su NOT NULL e nessun valore predefinito devono essere incluse, tutte le altre colonne verranno impostate sui valori predefiniti o NULL
travis

grazie per l'informazione
maheshmnj

148

Per ottenere un solo valore in un valore multiplo INSERTda un'altra tabella, ho fatto quanto segue in SQLite3:

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

4
Solo per chiarimenti: questo non è corretto per SQLite3. Come per la documentazione , i dati di origine per la INSERTtratta sia VALUES o SELECTdichiarazione, non entrambi.

2
È vero che la documentazione non la elenca, ma funziona. Indipendentemente da ciò, penso che l'uso dell'istruzione select anziché dei valori la renda più leggibile.
Banjocat,

1
Funziona per specificare un valore all'interno di una riga, ma il caso più generale richiede di ottenere molte righe.
Luchostein,

Se val_1 non cambia tra le righe, la seguente sintassi potrebbe funzionare in SQLite3? seleziona 'pippo', some_column da some_table - funziona in SQL Server 2014
Chris B

La documentazione elenca questo (ora?): Questa sintassi è INSERT INTO ... VALUES ([expr], [expr], ...)e uno dei percorsi [expr]è {{NOT} EXISTS} ([select-stmt])- nota che sono necessarie le paratesi attorno all'istruzione select (che {}significa facoltativo)
zapl

64

Entrambe le risposte che vedo funzionano bene in Informix in particolare e sono sostanzialmente SQL standard. Cioè, la notazione:

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

funziona bene con Informix e, mi aspetterei, tutto il DBMS. (Una volta 5 o più anni fa, questo è il genere di cose che MySQL non ha sempre supportato; ora ha un supporto decente per questo tipo di sintassi SQL standard e, AFAIK, funzionerebbe bene su questa notazione.) L'elenco delle colonne è facoltativo ma indica le colonne di destinazione in sequenza, quindi la prima colonna del risultato di SELECT andrà nella prima colonna elencata, ecc. In assenza dell'elenco di colonne, la prima colonna del risultato di SELECT va nella prima colonna della tabella di destinazione.

Ciò che può essere diverso tra i sistemi è la notazione utilizzata per identificare le tabelle in diversi database: lo standard non ha nulla da dire sulle operazioni tra database (per non parlare di inter-DBMS). Con Informix, è possibile utilizzare la seguente notazione per identificare una tabella:

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

Cioè, è possibile specificare un database, identificando facoltativamente il server che ospita quel database se non si trova nel server corrente, seguito da un proprietario facoltativo, punto e infine il nome effettivo della tabella. Lo standard SQL utilizza il termine schema per ciò che Informix chiama il proprietario. Pertanto, in Informix, una delle seguenti notazioni potrebbe identificare una tabella:

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

Il proprietario in generale non ha bisogno di essere quotato; tuttavia, se si utilizzano le virgolette, è necessario ottenere correttamente il nome del proprietario - diventa sensibile al maiuscolo / minuscolo. Questo è:

someone.table
"someone".table
SOMEONE.table

tutti identificano la stessa tabella. Con Informix, c'è una leggera complicazione con i database MODE ANSI, in cui i nomi dei proprietari vengono generalmente convertiti in maiuscolo (informix è l'eccezione). Cioè, in un database ANSI MODE (non comunemente usato), è possibile scrivere:

CREATE TABLE someone.table ( ... )

e il nome del proprietario nel catalogo di sistema sarebbe "QUALCUNO", piuttosto che "qualcuno". Se racchiudi il nome del proprietario tra virgolette doppie, si comporta come un identificatore delimitato. Con SQL standard, gli identificatori delimitati possono essere utilizzati in molti luoghi. Con Informix, puoi usarli solo attorno ai nomi dei proprietari: in altri contesti, Informix tratta sia le stringhe a virgoletta singola che quelle tra virgolette doppie come stringhe, anziché separare stringhe a virgoletta singola come stringhe e stringhe a virgolette doppie come identificatori delimitati. (Naturalmente, solo per completezza, esiste una variabile d'ambiente, DELIMIDENT, che può essere impostata - su qualsiasi valore, ma Y è la più sicura - per indicare che le virgolette doppie circondano sempre identificatori delimitati e le virgolette singole circondano sempre stringhe.)

Si noti che MS SQL Server riesce a utilizzare [identificatori delimitati] racchiusi tra parentesi quadre. Mi sembra strano, e certamente non fa parte dello standard SQL.


40

Per aggiungere qualcosa nella prima risposta, quando vogliamo solo pochi record da un'altra tabella (in questo esempio solo uno):

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

4
Questo approccio si applica solo a tale subquery che è selezionata solo una colonna. Nel caso di subquery a più colonne, verrà generato un errore "subquery deve restituire solo una colonna". Adotta quindi la risposta di @ travis.
snowfox,

34

La maggior parte dei database segue la sintassi di base,

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

Ogni banca dati Ho usato seguire questa sintassi cioè DB2, SQL Server, MY SQL,PostgresQL


34

Invece di VALUESparte della INSERTquery, basta usare la SELECTquery come di seguito.

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

32

Due approcci per l'inserimento in con query secondarie selezionate.

  1. Con SELECT subquery restituisce risultati con Una riga .
  2. Con SELECT subquery restituisce risultati con più righe .

1. Approccio per Con la subquery SELECT che restituisce risultati con una riga .

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

In questo caso, presuppone che la sottoquery SELECT restituisca solo una riga del risultato in base alla condizione WHERE o alle funzioni di aggregazione SQL come SUM, MAX, AVG ecc. Altrimenti genererà un errore

2. Approccio per Con la subquery SELECT che restituisce risultati con più righe .

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

Il secondo approccio funzionerà per entrambi i casi.


29

Questo può essere fatto senza specificare le colonne nella INSERT INTOparte se si stanno fornendo valori per tutte le colonne nella SELECTparte.

Diciamo che table1 ha due colonne. Questa query dovrebbe funzionare:

INSERT INTO table1
SELECT  col1, col2
FROM    table2

Questo NON funzionerebbe (il valore per col2non è specificato):

INSERT INTO table1
SELECT  col1
FROM    table2

Sto usando MS SQL Server. Non so come funzionano gli altri RDMS.


24

Questo è un altro esempio usando i valori con select:

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

Vecchia risposta e ancora utile. Abbastanza semplice e ovvio, ma copre esattamente le mie esigenze. Grazie!
Sebastian Kaczmarek,

21

Inserimento semplice quando è nota la sequenza di colonne della tabella:

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

Colonna di menzione di inserimento semplice:

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

Inserimento collettivo quando il numero di colonne selezionate di una tabella (# table2) è uguale alla tabella di inserimento (Table1)

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

Inserimento in blocco quando si desidera inserire solo nella colonna desiderata di una tabella (tabella1):

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

17

Ecco un altro esempio in cui l'origine viene presa utilizzando più di una tabella:

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;

17

Basta usare la parentesi per la clausola SELECT in INSERT. Ad esempio in questo modo:

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

Grazie @Das Funziona per me ....
Raj G

16

Ecco come inserire da più tabelle. Questo esempio particolare è dove hai una tabella di mappatura in molti o molti scenari:

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'

(Mi rendo conto che la corrispondenza sul nome dello studente potrebbe restituire più di un valore, ma si ottiene l'idea. La corrispondenza su qualcosa di diverso da un ID è necessaria quando l'id è una colonna di identità ed è sconosciuta.)


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

Funziona su tutti i DBMS


14

Puoi provare questo se vuoi inserire tutte le colonne usando la SELECT * INTOtabella.

SELECT  *
INTO    Table2
FROM    Table1;

13

In realtà preferisco quanto segue in 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 il passaggio dell'aggiunta del set Insert () e basta selezionare i valori da inserire nella tabella.


13

Questo ha funzionato per me:

insert into table1 select * from table2

La frase è leggermente diversa da quella di Oracle.


12

Per Microsoft SQL Server, consiglierò di imparare a interpretare il SYNTAX fornito su MSDN. Con Google è più facile che mai cercare la sintassi.

Per questo caso particolare, prova

Google: inserire il sito: microsoft.com

Il primo risultato sarà http://msdn.microsoft.com/en-us/library/ms174335.aspx

scorri verso il basso fino all'esempio ("Utilizzo delle opzioni SELEZIONA ed ESEGUI per inserire dati da altre tabelle") se trovi difficile interpretare la sintassi fornita nella parte superiore della pagina.

[ 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 
        }
    }
}
[;]

Questo dovrebbe essere applicabile per qualsiasi altro RDBMS disponibile lì. Non ha senso ricordare tutta la sintassi di tutti i prodotti IMO.


Sono completamente in disaccordo, ho guardato quelle dichiarazioni di sintassi per anni e ancora non riesco a farne testa o croce. Gli esempi sono molto più utili
reggaeguitar il

Questa non è una risposta, sta dicendo "leggi i documenti" e questo è tutto
reggaeguitar

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

@ggorlen Mi sembra abbastanza evidente
reggaeguitar

È stato segnalato nella coda di revisione come una risposta di solo codice. Posso vedere il tuo punto qui, però: non c'è molto da dire nel contesto della maggior parte delle risposte su questa pagina ora che lo vedo nel suo ambiente naturale.
Ggorlen,

9
select *
into tmp
from orders

Sembra carino, ma funziona solo se tmp non esiste (crea e riempie). (SQL sever)

Per inserire nella tabella tmp esistente:

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

9

Il modo migliore per inserire più record da qualsiasi altra tabella.

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)

2

Se segui il percorso INSERISCI VALORI per inserire più righe, assicurati di delimitare i VALORI in set usando le parentesi, quindi:

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

Altrimenti, MySQL afferma che "Il conteggio delle colonne non corrisponde al conteggio dei valori nella riga 1" e finisci per scrivere un post banale quando finalmente scopri cosa fare al riguardo.


6
La domanda è "inserire in una tabella usando l'input da un'altra tabella ". In che modo la tua risposta risponde a questa domanda?
Catalizzatore di qualità

3
Eh non essere troppo duro con lui. Ha risposto alla mia domanda mentre cercavo su Google. @QualityCatalyst
Cameron Belt

1

SE si desidera inserire alcuni dati in una tabella senza scrivere il nome della colonna.

INSERT INTO CUSTOMER_INFO
   (SELECT CUSTOMER_NAME,
           MOBILE_NO,
           ADDRESS
      FROM OWNER_INFO cm
     WHERE ID>100)

Dove sono le tabelle:

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

Risultato:

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

0

Informix funziona come ha detto Claude:

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

0

Postgres supporta next: crea la tabella company.monitor2 come seleziona * da company.monitor;

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.