Question Insérer dans ... valeurs (SELECT ... FROM ...)


J'essaie de INSERT INTO une table utilisant l'entrée d'une autre table. Bien que cela soit entièrement faisable pour de nombreux moteurs de base de données, je semble toujours avoir du mal à me souvenir de la syntaxe correcte pour SQL moteur du jour (MySQL, Oracle, serveur SQL, Informix, et DB2).

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


1093
2017-08-25 12:45


origine


Réponses:


Essayer:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

Ceci est la norme ANSI SQL et devrait fonctionner sur n'importe quel SGBD

Cela fonctionne définitivement pour:

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

1277
2017-08-25 12:47



@Shadow_x99: Cela devrait fonctionner correctement, et vous pouvez également avoir plusieurs colonnes et d'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;

Edit: Je dois mentionner que j'ai seulement utilisé cette syntaxe avec Access, SQL 2000/2005 / Express, MySQL et PostgreSQL, donc ceux-ci devraient être couverts. Un commentateur a fait remarquer que cela fonctionnera avec SQLite3.


775
2017-08-25 14:11



Pour obtenir une seule valeur dans une valeur multiple INSERT 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))

76
2018-01-10 23:46



Les deux réponses que je vois fonctionnent bien dans Informix spécifiquement, et sont fondamentalement SQL standard. Autrement dit, la notation:

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

fonctionne bien avec Informix et, je suppose, tous les SGBD. (Il y a 5 ans ou plus, c'est le genre de chose que MySQL ne supportait pas toujours, il supporte maintenant correctement ce type de syntaxe SQL standard et, AFAIK, cela fonctionnerait bien avec cette notation.) La liste des colonnes est facultatif mais indique les colonnes cibles en séquence, ainsi la première colonne du résultat du SELECT ira dans la première colonne listée, etc. En l'absence de la liste des colonnes, la première colonne du résultat du SELECT va dans le première colonne de la table cible.

Ce qui peut être différent entre les systèmes 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 sur 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 n'est pas dans le serveur actuel, suivi d'un propriétaire optionnel, d'un point, et enfin du nom de la table. La norme SQL utilise le terme schéma pour ce que Informix appelle le propriétaire. Ainsi, dans Informix, l'une 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é; Toutefois, si vous utilisez des guillemets, vous devez épeler correctement le nom du propriétaire, car il devient sensible à la casse. C'est:

someone.table
"someone".table
SOMEONE.table

tous identifient la même table. Avec Informix, il existe une légère complication avec les bases de données MODE ANSI, où les noms des propriétaires sont généralement convertis en majuscules (informix est l'exception). Autrement dit, dans une base de données MODE ANSI (pas 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 mettez le nom du propriétaire entre guillemets, il agit comme un identificateur délimité. Avec SQL standard, les identificateurs délimités peuvent être utilisés à plusieurs endroits. Avec Informix, vous pouvez les utiliser uniquement autour des noms de propriétaire. Dans d'autres contextes, Informix traite les chaînes entre guillemets simples et entre guillemets plutôt que de séparer les chaînes entre guillemets simples en tant que chaînes et guillemets entre guillemets. (Bien sûr, juste pour être complet, il existe une variable d'environnement, DELIMIDENT, qui peut être définie - à 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 [identificateurs délimités] entre crochets. Cela me semble bizarre et ne fait certainement pas partie de la norme SQL.


52
2017-09-28 03:18



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


26
2018-04-01 10:09



Pour ajouter quelque chose dans la première réponse, quand on veut 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);

26
2018-04-09 17:15



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

Disons que table1 a 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 spécifié):

INSERT INTO table1
SELECT  col1
FROM    table2

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


22
2017-10-16 14:19



Voici un autre exemple utilisant des valeurs avec select:

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

16
2018-03-20 09:12



Insertion simple lorsque la séquence de colonnes de la table est connue:

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

Colonne de mention d'insertion simple:

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

Insertion en bloc lorsque le nombre de colonnes sélectionnées d'une table (# table2) est égal à la table d'insertion (Table1)

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

Insertion en bloc lorsque vous souhaitez insérer uniquement dans la colonne souhaitée d'une table (table1):

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

15
2018-02-13 12:23



C'est simple, au lieu de VALUES partie de INSERT requête, juste utiliser SELECT requête comme ci-dessous.

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

10
2018-04-21 10:31