Insérer dans ... valeurs (sélectionner ... de …)
j'essaie de INSERT INTO
une table en utilisant l'entrée d'une autre table. Bien que cela soit tout à fait faisable pour de nombreux moteurs de base de données, je semble toujours avoir du mal à me souvenir de la syntaxe correcte pour le moteur SQL
du jour ( MySQL , Oracle , SQL Server , Informix , et DB2 ).
y a-t-il une syntaxe à balle argentée venant de une norme SQL (par exemple, SQL-92 ) qui me permettrait d'insérer les valeurs sans me soucier de la base de données sous-jacente?
22 réponses
, Essayez:
INSERT INTO table1 ( column1 )
SELECT col1
FROM table2
ceci est standard ANSI SQL et devrait fonctionner sur N'importe quel SGBD
Cela fonctionne bien pour:
- Oracle
- MS SQL Server
- MySQL
- Postgres
- SQLite v3
- Teradata
- DB2
- Sybase
- Vertica
- HSQLDB
- H2
- AWS RedShift
- SAP HANA
@ Shadow_x99 : cela devrait fonctionner très bien, et vous pouvez également avoir plusieurs colonnes et d'autres données ainsi:
INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT table2.column1, table2.column2, 8, 'some string etc.'
FROM table2
WHERE table2.ID = 7;
Edit: je tiens à préciser que je n'ai utilisé cette syntaxe avec Access, SQL 2000/2005/Express, MySQL et PostgreSQL, de sorte que ceux-ci devraient être couverts. Un commentateur a fait remarquer que cela fonctionnerait avec SQLite3.
pour obtenir une seule valeur dans une valeur multiple INSERT
d'une autre table j'ai fait ce qui suit 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))
les deux réponses que je vois fonctionnent bien dans Informix spécifiquement, et sont essentiellement SQL standard. C'est-à-dire la notation:
INSERT INTO target_table[(<column-list>)] SELECT ... FROM ...;
fonctionne très bien avec Informix et, je pense, tous les SGBD. (Il y a 5 ans ou plus, C'est le genre de chose que MySQL n'a pas toujours supporté; il a maintenant un support décent pour ce genre de syntaxe SQL standard et, AFAIK, il fonctionnerait bien sur cette notation.) La liste des colonnes est optionnelle mais indique les colonnes cibles dans l'ordre, 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 la première colonne du tableau 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 inter-DBMS). Avec Informix, vous pouvez utiliser ce qui suit: notation pour identifier une table:
[dbase[@server]:][owner.]table
C'est-à-dire que vous pouvez spécifier une base de données, identifiant en option le serveur qui héberge cette base de données s'il n'est pas dans le serveur courant, suivi d'un propriétaire optionnel, d'un point, et finalement du nom de la table réelle. La norme SQL utilise le terme schema pour ce Qu'Informix appelle le propriétaire. Ainsi, dans Informix, l'une des notations suivantes pourrait identifier un tableau:
table
"owner".table
dbase:table
dbase:owner.table
dbase@server:table
dbase@server:owner.table
le propriétaire en général ne besoin d'être cité; cependant, si vous utilisez des citations, vous devez obtenir le nom du propriétaire orthographié correctement - il devient sensible à la casse. C'est-à-dire:
someone.table
"someone".table
SOMEONE.table
identifient tous la même table. Avec Informix, il y a 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). C'est-à-dire, dans un MODE ANSI base de données (pas couramment utilisé), vous pourriez é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 identifiant délimité. Avec le SQL standard, les identificateurs délimités peuvent être utilisés à de nombreux endroits. Avec Informix, vous ne pouvez les utiliser qu'autour des noms de propriétaires -- dans d'autres contextes, Informix traite les chaînes à simple et double guillemets comme des chaînes, plutôt que de séparer les chaînes à simple guillemet comme des chaînes et les chaînes à double guillemet comme des identificateurs délimités. (Bien sûr, juste pour être complet, il y a une variable D'environnement, DELIMIDENT, qui peut être définie - à n'importe quelle valeur, mais Y est le plus sûr - pour indiquer que les guillemets entourent toujours les identificateurs délimités et les guillemets entourent toujours les chaînes.)
notez que MS SQL Server parvient à utiliser [des identificateurs délimités] entre crochets. Il semble bizarre pour moi, et ne fait certainement pas partie de la norme 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, quand 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);
ceci peut être fait sans spécifier les colonnes dans la partie INSERT INTO
si vous fournissez des valeurs pour toutes les colonnes dans la partie SELECT
.
supposons que le tableau 1 comporte deux colonnes. Cette requête devrait fonctionner:
INSERT INTO table1
SELECT col1, col2
FROM table2
cela ne fonctionnerait pas (la valeur de col2
n'est pas spécifiée):
INSERT INTO table1
SELECT col1
FROM table2
j'utilise le serveur MS SQL. Je ne sais pas comment fonctionnent les autres DGR.
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 de la colonne du tableau est connue:
Insert into Table1
values(1,2,...)
colonne d'insertion simple mentionnant:
Insert into Table1(col2,col4)
values(1,2)
Insertion En Vrac lorsque le nombre de colonnes sélectionnées d'un tableau(#tableau2) est égal à table d'insertion (Tableau1)
Insert into Table1 {Column sequence}
Select * -- column sequence should be same.
from #table2
insertion en vrac lorsque vous voulez insérer seulement dans la colonne désirée d'un tableau(Tableau1):
Insert into Table1 (Column1,Column2 ....Desired Column from Table1)
Select Column1,Column2..desired column from #table2
from #table2
au lieu de VALUES
partie de INSERT
requête, il suffit d'utiliser SELECT
requête comme ci-dessous.
INSERT INTO table1 ( column1 , 2, 3... )
SELECT col1, 2, 3... FROM table2
Voici comment insérer à partir de plusieurs tables. Cet exemple particulier est celui où vous avez une table de correspondance dans plusieurs scénarios:
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 me rends compte que la correspondance sur le nom de l'étudiant peut rapporter plus d'une valeur, mais vous avez l'idée. Correspondance sur autre chose qu'un Id est nécessaire lorsque l'Id est une colonne d'Identité et est inconnu.)
voici un autre exemple où la source est prise en utilisant plus d'un tableau:
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;
INSERT INTO yourtable
SELECT fielda, fieldb, fieldc
FROM donortable;
cela fonctionne sur tous les SGBD
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.
dans ce cas précis, essayez
Google: insérer site:microsoft.com
le premier résultat sera http://msdn.microsoft.com/en-us/library/ms174335.aspx
faites défiler vers le bas exemple ("utiliser les options SELECT et EXECUTE pour insérer des données d'autres tables") si vous trouvez difficile d'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
}
}
}
[;]
cette disposition devrait s'appliquer à tout autre SGBDR disponible à cet endroit. Il est inutile de se rappeler toute la syntaxe pour tous les produits IMO.
vous pouvez essayer ceci si vous voulez insérer toute la colonne en utilisant SELECT * INTO
table.
SELECT *
INTO Table2
FROM Table1;
je préfère en fait 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
il élimine l'étape de l'ajout de L'ensemble Insert (), et vous sélectionnez simplement quelles valeurs vont dans la table.
select *
into tmp
from orders
semble agréable, mais ne fonctionne que si tmp n'existe pas (le crée et le remplit). (SQL sever)
à insérer dans le tableau tmp existant:
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
meilleure façon d'insérer plusieurs enregistrements 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)
il suffit d'utiliser les parenthèses pour sélectionner clause dans insérer. 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'
);
si vous allez à la route INSERT VALUES pour insérer plusieurs lignes, assurez-vous de délimiter les valeurs en ensembles en utilisant des parenthèses, ainsi:
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');
Autrement les objets MySQL que "Column count doesn't match value count at row 1", et vous finissez par écrire un banal message lorsque vous enfin comprendre ce qu'il faut faire à ce sujet.
INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT COLUMN_NAME
FROM ANOTHER_TABLE_NAME
WHERE CONDITION;