Question

J'essaie de INSERT INTO une table en utilisant l'entrée d'une autre table.Bien que cela soit tout à fait réalisable pour de nombreux moteurs de bases de données, j'ai toujours du mal à me souvenir de la syntaxe correcte pour le SQL moteur du jour (MySQL, Oracle, serveur SQL, Informix, et DB2).

Existe-t-il une syntaxe miracle provenant d'un standard SQL (par exemple, SQL-92) cela me permettrait d'insérer les valeurs sans me soucier de la base de données sous-jacente ?

Était-ce utile?

La solution

Essayer:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

Il s'agit d'ANSI SQL standard et devrait fonctionner sur n'importe quel SGBD.

Cela fonctionne définitivement pour :

  • Oracle
  • Serveur MS SQL
  • MySQL
  • PostgreSQL
  • SQLite v3
  • Teradata
  • DB2
  • Sybase
  • Vertique
  • HSQLDB
  • H2
  • AWSRedShift
  • SAP HANA

Autres conseils

@Ombre_x99:Cela devrait fonctionner correctement, et vous pouvez également avoir plusieurs colonnes et autres données :

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

Modifier:Je dois mentionner que je n'ai utilisé cette syntaxe qu'avec Access, SQL 2000/2005/Express, MySQL et PostgreSQL, celles-ci devraient donc être couvertes.Un commentateur a souligné que cela fonctionnerait avec SQLite3.

Pour obtenir une seule valeur dans une valeur multiple INSERT à partir d'une autre table, j'ai fait ce qui suit dans SQLite3 :

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

Les deux réponses que je vois fonctionnent spécifiquement dans Informix et sont essentiellement du SQL standard.C'est-à-dire la notation :

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

fonctionne bien avec Informix et, je m'attendrais, avec tous les SGBD.(Il y a 5 ans ou plus, c'est le genre de chose que MySQL n'a pas toujours pris en charge ;il prend désormais en charge correctement ce type de syntaxe SQL standard et, AFAIK, cela fonctionnerait correctement avec cette notation.) La liste des colonnes est facultative mais indique les colonnes cibles dans l'ordre, donc la première colonne du résultat du SELECT ira dans la première colonne répertoriée, etc.En l'absence de liste de colonnes, la première colonne du résultat du SELECT va dans la première colonne de la table cible.

Ce qui peut être différent entre les systèmes, c'est la notation utilisée pour identifier les tables dans différentes bases de données - la norme n'a rien à dire sur les opérations inter-bases de données (et encore moins inter-SGBD).Avec Informix, vous pouvez utiliser la notation suivante pour identifier une table :

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

Autrement dit, vous pouvez spécifier une base de données, en identifiant éventuellement le serveur qui héberge cette base de données si elle ne se trouve pas sur le serveur actuel, suivi d'un propriétaire facultatif, d'un point et enfin du nom réel de la table.La norme SQL utilise le terme schéma pour désigner ce qu'Informix appelle le propriétaire.Ainsi, dans Informix, n'importe laquelle des notations suivantes pourrait identifier une table :

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

Le propriétaire en général n’a pas besoin d’être cité ;cependant, si vous utilisez des guillemets, vous devez épeler correctement le nom du propriétaire – il devient sensible à la casse.C'est-à-dire:

someone.table
"someone".table
SOMEONE.table

tous identifient le même tableau.Avec Informix, il existe une légère complication avec les bases de données MODE ANSI, où les noms de propriétaires sont généralement convertis en majuscules (informix est l'exception).Autrement dit, dans une base de données MODE ANSI (peu couramment utilisée), vous pouvez écrire :

CREATE TABLE someone.table ( ... )

et le nom du propriétaire dans le catalogue système serait « QUELQU'UN » plutôt que « quelqu'un ».Si vous placez le nom du propriétaire entre guillemets, il agit comme un identifiant délimité.Avec le SQL standard, les identifiants délimités peuvent être utilisés à plusieurs endroits.Avec Informix, vous pouvez les utiliser uniquement autour des noms de propriétaires. Dans d'autres contextes, Informix traite les chaînes entre guillemets simples et doubles comme des chaînes, plutôt que de séparer les chaînes entre guillemets simples en tant que chaînes et les chaînes entre guillemets doubles en tant qu'identifiants délimités.(Bien sûr, par souci d'exhaustivité, il existe une variable d'environnement, DELIMIDENT, qui peut être définie - sur n'importe quelle valeur, mais Y est la plus sûre - pour indiquer que les guillemets doubles entourent toujours les identifiants délimités et que les guillemets simples entourent toujours les chaînes.)

Notez que MS SQL Server parvient à utiliser des [identifiants délimités] entre crochets.Cela me semble bizarre et ne fait certainement pas partie du standard SQL.

La plupart des bases de données suivent la syntaxe de base,

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

Chaque base de données que j'ai utilisée suit cette syntaxe, à savoir : DB2, SQL Server, MY SQL, PostgresQL

Pour ajouter quelque chose dans la première réponse, lorsque nous voulons seulement quelques enregistrements d'une autre table (dans cet exemple un seul) :

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

Cela peut être fait sans spécifier les colonnes dans le INSERT INTO partie si vous fournissez des valeurs pour toutes les colonnes du SELECT partie.

Disons que la table1 comporte deux colonnes.Cette requête devrait fonctionner :

INSERT INTO table1
SELECT  col1, col2
FROM    table2

Cela NE FONCTIONNERAIT PAS (valeur pour col2 n'est pas précisé) :

INSERT INTO table1
SELECT  col1
FROM    table2

J'utilise MS SQL Server.Je ne sais pas comment fonctionnent les autres RDMS.

Au lieu de VALUES partie de INSERT requête, utilisez simplement SELECT requête comme ci-dessous.

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

Ceci est un autre exemple utilisant des valeurs avec select :

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

Insertion simple lorsque la séquence des colonnes du tableau est connue :

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

Colonne de mention d'insertion simple :

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

Insertion groupée lorsque le nombre de colonnes sélectionnées d'un tableau (#table2) est égal au tableau d'insertion (Tableau1)

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

Insertion groupée lorsque vous souhaitez insérer uniquement dans la colonne souhaitée d'un tableau (table1) :

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

Voici un autre exemple où la source est prise en utilisant plusieurs tables :

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;

Voici comment insérer à partir de plusieurs tables.Cet exemple particulier est celui où vous disposez d'une table de mappage dans un scénario plusieurs à plusieurs :

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'

(Je réalise que la correspondance avec le nom de l'étudiant peut renvoyer plus d'une valeur, mais vous voyez l'idée.La correspondance sur autre chose qu'un identifiant est nécessaire lorsque l'identifiant est une colonne d'identité et est inconnu.)

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

Cela fonctionne sur tous les SGBD

Vous pouvez essayer ceci si vous souhaitez insérer toutes les colonnes en utilisant SELECT * INTO tableau.

SELECT  *
INTO    Table2
FROM    Table1;

Cela a fonctionné pour moi :

insert into table1 select * from table2

La phrase est un peu différente de celle d'Oracle.

Pour Microsoft SQL Server, je recommanderai d'apprendre à interpréter la SYNTAXE fournie sur MSDN.Avec Google, il est plus facile que jamais de rechercher la syntaxe.

Pour ce cas particulier, essayez

Google:insérer le site :microsoft.com

Le premier résultat sera http://msdn.microsoft.com/en-us/library/ms174335.aspx

faites défiler jusqu'à l'exemple ("Utilisation des options SELECT et EXECUTE pour insérer des données provenant d'autres tables") si vous avez du mal à interpréter la syntaxe donnée en haut de la page.

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

Cela devrait être applicable à tout autre SGBDR disponible ici.Il ne sert à rien de mémoriser toute la syntaxe de tous les produits IMO.

En fait, je préfère ce qui suit dans 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

Cela élimine l'étape d'ajout de l'ensemble Insert () et il vous suffit de sélectionner les valeurs qui doivent figurer dans le tableau.

Utilisez simplement des parenthèses pour SÉLECTIONNER clause dans INSERT.Par exemple comme ceci :

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'
);
select *
into tmp
from orders

Ça a l'air sympa, mais ne fonctionne que si tmp n'existe pas (le crée et le remplit).(serveur SQL)

Pour insérer dans une table tmp existante :

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

Meilleur moyen d'insérer plusieurs enregistrements à partir de n'importe quelle autre table.

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)
INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT  COLUMN_NAME
FROM    ANOTHER_TABLE_NAME 
WHERE CONDITION;

Deux approches pour l'insertion avec une sous-requête de sélection.

  1. Avec la sous-requête SELECT renvoyant les résultats avec Une rangée.
  2. Avec la sous-requête SELECT renvoyant les résultats avec Plusieurs lignes.

1.Approche pour la sous-requête With SELECT renvoyant des résultats avec une rangée.

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

Dans ce cas, cela suppose que la sous-requête SELECT ne renvoie qu'une seule ligne de résultat basée sur la condition WHERE ou les fonctions d'agrégation SQL telles que SUM, MAX, AVG, etc.Sinon, cela générera une erreur

2.Approche pour la sous-requête With SELECT renvoyant des résultats avec plusieurs lignes.

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

La deuxième approche fonctionnera dans les deux cas.

Si vous suivez la route INSERT VALUES pour insérer plusieurs lignes, assurez-vous de délimiter les VALUES en ensembles à l'aide de parenthèses, donc :

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

Sinon, MySQL objecte que "le nombre de colonnes ne correspond pas au nombre de valeurs à la ligne 1", et vous finissez par écrire un article trivial lorsque vous savez enfin quoi faire à ce sujet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top