Invoegen in … waarden ( SELECT … FROM … )

Ik probeer een tabel INSERT INTOte gebruiken met de invoer van een andere tabel. Hoewel dit voor veel database-engines heel goed mogelijk is, lijk ik altijd moeite te hebben om de juiste syntaxis te onthouden voor de SQL-engine van de dag (MySQL, Oracle, SQL-server, Informixen DB2).

Is er een silver-bullet-syntaxis afkomstig van een SQL-standaard (bijvoorbeeld SQL-92) waarmee ik de waarden kan invoegen zonder me zorgen te hoeven maken over de onderliggende database?


Antwoord 1, autoriteit 100%

Probeer:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

Dit is standaard ANSI SQL en zou op elk DBMS moeten werken

Het werkt zeker voor:

  • Oracle
  • MS SQL Server
  • MijnSQL
  • Postgres
  • SQLite v3
  • Teradata
  • DB2
  • Sybase
  • Vertica
  • HSQLDB
  • H2
  • AWS RedShift
  • SAP HANA
  • Google Spanner

Antwoord 2, autoriteit 62%

Het antwoord van Claude Houle: zou goed moeten werken, en je kunt ook meerdere kolommen en andere gegevens hebben:

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

Ik heb deze syntaxis alleen gebruikt met Access, SQL 2000/2005/Express, MySQL en PostgreSQL, dus die zouden behandeld moeten worden. Het zou ook moeten werken met SQLite3.


Antwoord 3, autoriteit 10%

Om slechts één waarde in een INSERTmet meerdere waarden uit een andere tabel te krijgen, deed ik het volgende 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))

Antwoord 4, autoriteit 4%

Beide antwoorden die ik zie werken prima in Informix specifiek, en zijn in feite standaard SQL. Dat wil zeggen, de notatie:

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

werkt prima met Informix en, naar ik zou verwachten, alle DBMS. (Eens 5 jaar of langer geleden was dit het soort dingen dat MySQL niet altijd ondersteunde; het heeft nu behoorlijke ondersteuning voor dit soort standaard SQL-syntaxis en, AFAIK, het zou goed werken met deze notatie.) De kolomlijst is optioneel maar geeft de doelkolommen in volgorde aan, dus de eerste kolom van het resultaat van de SELECT komt in de eerste vermelde kolom, enz. Bij afwezigheid van de kolomlijst, gaat de eerste kolom van het resultaat van de SELECT in de eerste kolom van de doeltabel.

Wat tussen systemen kan verschillen, is de notatie die wordt gebruikt om tabellen in verschillende databases te identificeren – de standaard heeft niets te zeggen over operaties tussen databases (laat staan inter-DBMS). Met Informix kunt u de volgende notatie gebruiken om een tabel te identificeren:

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

Dat wil zeggen, u kunt een database specificeren, waarbij u optioneel de server identificeert die de database host als deze zich niet op de huidige server bevindt, gevolgd door een optionele eigenaar, punt en tenslotte de werkelijke tabelnaam. De SQL-standaard gebruikt de term schema voor wat Informix de eigenaar noemt. In Informix kan dus elk van de volgende notaties een tabel identificeren:

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

De eigenaar hoeft in het algemeen niet vermeld te worden; Als u echter aanhalingstekens gebruikt, moet u de naam van de eigenaar correct gespeld hebben – deze wordt hoofdlettergevoelig. Dat is:

someone.table
"someone".table
SOMEONE.table

allemaal dezelfde tabel. Met Informix is er een milde complicatie met MODE ANSI-databases, waar namen van eigenaren over het algemeen worden omgezet in hoofdletters (informix is de uitzondering). Dat wil zeggen, in een MODE ANSI-database (niet vaak gebruikt), zou je kunnen schrijven:

CREATE TABLE someone.table ( ... )

en de naam van de eigenaar in de systeemcatalogus zou “IEMAND” zijn in plaats van “iemand”. Als u de naam van de eigenaar tussen dubbele aanhalingstekens plaatst, werkt deze als een identificatie met scheidingstekens. Met standaard SQL kunnen gescheiden identifiers op veel plaatsen worden gebruikt. Met Informix kunt u ze alleen gebruiken rond namen van eigenaren — in andere contexten behandelt Informix zowel enkelvoudige als dubbele aanhalingstekens als tekenreeksen, in plaats van enkelvoudige aanhalingstekens te scheiden als tekenreeksen en dubbele aanhalingstekens als identifiers met scheidingstekens. (Voor de volledigheid is er natuurlijk een omgevingsvariabele, DELIMIDENT, die kan worden ingesteld – op elke waarde, maar Y is het veiligst – om aan te geven dat dubbele aanhalingstekens altijd gescheiden identifiers omringen en enkele aanhalingstekens altijd tekenreeksen.)

Merk op dat MS SQL Server erin slaagt [delimited identifiers] tussen vierkante haken te gebruiken. Het ziet er raar uit en maakt zeker geen deel uit van de SQL-standaard.


Antwoord 5, autoriteit 3%

Twee benaderingen voor invoegen in met select subquery.

  1. Met SELECT subquery die resultaten retourneert met Eén rij.
  2. Met SELECT subquery die resultaten retourneert met Meerdere rijen.

1. Aanpak voor With SELECT subquery die resultaten retourneert met één rij.

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

In dit geval wordt ervan uitgegaan dat de SELECT-subquery slechts één rij met resultaten retourneert op basis van de WHERE-voorwaarde of SQL-aggregatiefuncties zoals SUM, MAX, AVG enz. Anders wordt er een fout gegenereerd

2. Aanpak voor With SELECT subquery die resultaten retourneert met meerdere rijen.

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

De tweede aanpak zal voor beide gevallen werken.


6, Autoriteit 3%

Om iets in het eerste antwoord toe te voegen, wanneer we maar weinig records van een andere tabel willen (in dit voorbeeld slechts één):

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

7, Autoriteit 2%

In plaats van VALUESdeel van INSERTquery, gebruik gewoon SELECTquery zoals hieronder.

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

8, Autoriteit 2%

Dit kan worden gedaan zonder de kolommen in de INSERT INTOonderdeel als u waarden levert voor alle kolommen in de SELECTPart.

Laten we zeggen dat Table1 twee kolommen heeft. Deze query zou moeten werken:

INSERT INTO table1
SELECT  col1, col2
FROM    table2

Dit zou niet werken (waarde voor col2is niet opgegeven):

INSERT INTO table1
SELECT  col1
FROM    table2

Ik gebruik MS SQL Server. Ik weet niet hoe andere RDMS werken.


Antwoord 9

Dit is een ander voorbeeld waarbij waarden worden gebruikt met select:

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

Antwoord 10

Eenvoudige invoeging wanneer de kolomvolgorde van de tabel bekend is:

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

Eenvoudige invoeging met vermelding van kolom:

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

Bulk invoegen wanneer het aantal geselecteerde kolommen van een tabel (#table2) gelijk is aan invoegtabel (Tabel1)

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

Bulk invoegen wanneer u alleen in de gewenste kolom van een tabel(tabel1) wilt invoegen:

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

Antwoord 11

Gebruik gewoon haakjes voor de SELECT-clausule in INSERT. Bijvoorbeeld als volgt:

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

Antwoord 12

Hier is nog een voorbeeld waarbij de bron is genomen met meer dan één tabel:

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;

Antwoord 13

Hier leest u hoe u kunt invoegen vanuit meerdere tabellen. In dit specifieke voorbeeld heb je een toewijzingstabel in een veel-op-veel scenario:

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'

(Ik realiseer me dat het matchen op de naam van de student meer dan één waarde kan opleveren, maar je snapt het idee. Het matchen op iets anders dan een Id is nodig wanneer de Id een Identiteitskolom is en onbekend is.)


Antwoord 14

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

Dit werkt op alle DBMS


Antwoord 15

Je zou dit kunnen proberen als je alle kolommen wilt invoegen met behulp van de SELECT * INTOtabel.

SELECT  *
INTO    Table2
FROM    Table1;

Antwoord 16

Ik geef eigenlijk de voorkeur aan het volgende 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

Het elimineert de stap van het toevoegen van de Insert () set, en je gewoon kiezen welke waarden gaan in de tabel.


17

Dit werkte voor mij:

insert into table1 select * from table2

De zin is een beetje anders dan Oracle’s.


18

Voor Microsoft SQL Server, ik zal aanbevelen leren om de syntaxis die op MSDN interpreteren. Met Google is het gemakkelijker dan ooit, op zoek naar syntax.

Voor dit specifieke geval, probeer dan

Google: insert website: microsoft.com

Het eerste resultaat zal zijn http://msdn.microsoft.com/en -us / bibliotheek / ms174335.aspx

scroll naar beneden naar het voorbeeld ( “Gebruik van het selecteren en uitvoeren opties om gegevens uit andere tabellen invoegen”) als u het moeilijk vindt om de syntaxis gegeven aan de bovenkant van de pagina te interpreteren.

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

Dit moet van toepassing zijn op andere RDBMS beschikbaar. Het heeft geen zin om alle syntaxis voor alle producten IMO te onthouden.


19

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

20

Beste manier om meerdere records van andere tabellen in te voegen.

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)

21

select *
into tmp
from orders

Ziet er goed uit, maar werkt alleen als TMP niet bestaat (maakt het en vult). (SQL Sever)

Invoegen in de bestaande TMP-tabel:

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

Antwoord 22

ALS u wat gegevens in een tabel wilt invoegen zonder de kolomnaam te willen schrijven.

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

Waar de tabellen zijn:

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

Resultaat:

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

Antwoord 23

Als u de INSERT VALUES-route volgt om meerdere rijen in te voegen, zorg er dan voor dat u de VALUES in sets begrenst met haakjes, dus:

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

Anders MySQL-objecten die “kolomcellen niet overeenkomen met de waarde Count op rij 1”, en u maakt uiteindelijk een triviale post op wanneer u eindelijk kunt achterhalen wat eraan doet.


24

Informix werkt het als Claude zei:

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

25

Postgres ondersteunt Volgende:
Create Table Company.monitor2 als selecte * van bedrijf.monitor;


26

INSERT INTO Table_Name (COL1, COL2, COL3, ...)
VALUES (Value1, Value2, Value3, ...);

met schema naam (zoals in Postgresql):

INSERT INTO "Schema-name"."Table_Name" (COL1, COL2, COL3, ...)
VALUES (Value1, Value2, Value3, ...);

27

Als u eerst een tabel maakt, kunt u dit zo gebruiken;

 select * INTO TableYedek From Table

Deze Metot-invoegtelwaarden, maar anders met het maken van een nieuwe kopieertabel.

Other episodes