INSERT INTO
別のテーブルからの入力を使用してテーブルを作成しようとしています。SQL
これは多くのデータベース エンジンで完全に実行可能ですが、現在のエンジン ( MySQL、Oracle、SQL Server、Informix、およびDB2 )の正しい構文を覚えるのにいつも苦労しているようです。
基になるデータベースを気にせずに値を挿入できる、SQL 標準 ( SQL-92など)からの特効薬の構文はありますか?
試す:
INSERT INTO table1 ( column1 )
SELECT col1
FROM table2
これは標準の ANSI SQL であり、あらゆる DBMS で動作するはずです。
それは間違いなく機能します:
Claude Houle's answer : 正常に動作するはずです。また、複数の列やその他のデータを使用することもできます。
INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT table2.column1, table2.column2, 8, 'some string etc.'
FROM table2
WHERE table2.ID = 7;
この構文は、Access、SQL 2000/2005/Express、MySQL、および PostgreSQL でしか使用していないため、それらについて説明する必要があります。SQLite3 でも動作するはずです。
私が見る答えはどちらも Informix で特に問題なく機能し、基本的には標準 SQL です。つまり、表記は次のとおりです。
INSERT INTO target_table[(<column-list>)] SELECT ... FROM ...;
Informix や、すべての DBMS で問題なく動作します。(5 年以上前に、これは MySQL が常にサポートしていたわけではありませんでした。現在では、この種の標準 SQL 構文を適切にサポートしており、私の知る限り、この表記法で問題なく動作します。) 列リストはオプションですが、順番にターゲット列を示します。そのため、SELECT の結果の最初の列は最初にリストされた列に入ります。列リストがない場合、SELECT の結果の最初の列はターゲット表の最初の列。
システム間で異なる可能性があるのは、異なるデータベース内のテーブルを識別するために使用される表記法です。標準では、データベース間 (ましてや DBMS 間) の操作については何も述べていません。Informix では、次の表記を使用してテーブルを識別できます。
[dbase[@server]:][owner.]table
つまり、データベースを指定し、そのデータベースが現在のサーバーにない場合はオプションでそのデータベースをホストするサーバーを指定し、その後にオプションの所有者、ドット、最後に実際のテーブル名を続けます。SQL 標準では、Informix が所有者と呼ぶものに対してスキーマという用語を使用しています。したがって、Informix では、次の表記のいずれかでテーブルを識別できます。
table
"owner".table
dbase:table
dbase:owner.table
dbase@server:table
dbase@server:owner.table
通常、所有者を引用する必要はありません。ただし、引用符を使用する場合は、所有者名のスペルを正しくする必要があります。大文字と小文字が区別されます。あれは:
someone.table
"someone".table
SOMEONE.table
すべて同じテーブルを識別します。Informix では、所有者名が一般に大文字に変換される MODE ANSI データベースとの複雑な問題があります (informix は例外です)。つまり、MODE ANSI データベース (一般的には使用されません) では、次のように記述できます。
CREATE TABLE someone.table ( ... )
また、システム カタログの所有者名は、「someone」ではなく「SOMEONE」になります。所有者名を二重引用符で囲むと、区切り識別子のように機能します。標準 SQL では、区切り識別子をさまざまな場所で使用できます。Informix では、所有者名の周囲でのみ使用できます。他のコンテキストでは、Informix は、単一引用符で囲まれた文字列を文字列として、二重引用符で囲まれた文字列を区切り識別子として分離するのではなく、単一引用符で囲まれた文字列と二重引用符で囲まれた文字列の両方を文字列として扱います。(もちろん、完全を期すために、任意の値に設定できる環境変数 DELIMIDENT がありますが、Y が最も安全です。これは、二重引用符が区切り記号で区切られた識別子を常に囲み、単一引用符が常に文字列を囲むことを示します。)
MS SQL Server は、角括弧で囲まれた [区切り識別子] を使用することに注意してください。私には奇妙に見えますが、確かに SQL 標準の一部ではありません。
サブクエリを選択して挿入するための2つのアプローチ。
1. 1 行で結果を返す With SELECT サブクエリへのアプローチ.
INSERT INTO <table_name> (<field1>, <field2>, <field3>)
VALUES ('DUMMY1', (SELECT <field> FROM <table_name> ),'DUMMY2');
この場合、SELECT サブクエリは、WHERE 条件または SUM、MAX、AVG などの SQL 集計関数に基づいて 1 行の結果のみを返すと想定しています。それ以外の場合は、エラーがスローされます。
2.複数行の結果を返す With SELECT サブクエリへのアプローチ.
INSERT INTO <table_name> (<field1>, <field2>, <field3>)
SELECT 'DUMMY1', <field>, 'DUMMY2' FROM <table_name>;
2 番目のアプローチは、両方のケースで機能します。
最初の回答に何かを追加するには、別のテーブルからいくつかのレコードのみが必要な場合 (この例では 1 つだけ):
INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3, COLUMN4)
VALUES (value1, value2,
(SELECT COLUMN_TABLE2
FROM TABLE2
WHERE COLUMN_TABLE2 like "blabla"),
value4);
クエリのVALUES
一部の代わりに、以下のようにクエリを使用してください。INSERT
SELECT
INSERT INTO table1 ( column1 , 2, 3... )
SELECT col1, 2, 3... FROM table2
ほとんどのデータベースは基本的な構文に従います。
INSERT INTO TABLE_NAME
SELECT COL1, COL2 ...
FROM TABLE_YOU_NEED_TO_TAKE_FROM
;
私が使用したすべてのデータベースは、この構文、つまり、、、、に従いDB2
ますSQL Server
MY SQL
PostgresQL
これは、INSERT INTO
パーツ内のすべての列に値を指定する場合、パーツ内の列を指定しなくても実行できますSELECT
。
table1 に 2 つの列があるとします。このクエリは機能するはずです:
INSERT INTO table1
SELECT col1, col2
FROM table2
これは機能しません (値col2
が指定されていません):
INSERT INTO table1
SELECT col1
FROM table2
MS SQL Server を使用しています。他の RDMS がどのように機能するかはわかりません。
これは、select で値を使用する別の例です。
INSERT INTO table1(desc, id, email)
SELECT "Hello World", 3, email FROM table2 WHERE ...
複数のテーブルを使用してソースを取得する別の例を次に示します。
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 StudentCourseMap (StudentId, CourseId)
SELECT Student.Id, Course.Id FROM Student, Course
WHERE Student.Name = 'Paddy Murphy' AND Course.Name = 'Basket weaving for beginners'
(学生名の照合で複数の値が返される可能性があることは理解していますが、おわかりいただけると思います。Id が Identity 列であり、不明な場合は、ID 以外の照合が必要です。)
テーブルを使用してすべての列を挿入する場合は、これを試すことができSELECT * INTO
ます。
SELECT *
INTO Table2
FROM Table1;
INSERT INTO yourtable
SELECT fielda, fieldb, fieldc
FROM donortable;
これはすべての DBMS で機能します
これは私のために働いた:
insert into table1 select * from table2
この文はオラクルのものとは少し異なります。
私は実際には、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
これにより、Insert () セットを追加するステップが不要になり、テーブルに入れる値を選択するだけです。
Microsoft SQL Server については、MSDN で提供されている SYNTAX の解釈を学ぶことをお勧めします。Google を使用すると、これまでになく簡単に構文を検索できます。
この特定のケースでは、試してください
Google: サイトを挿入:microsoft.com
最初の結果はhttp://msdn.microsoft.com/en-us/library/ms174335.aspxになります
ページの上部にある構文を解釈するのが難しい場合は、下にスクロールして例 (「SELECT および EXECUTE オプションを使用して他のテーブルからデータを挿入する」) を参照してください。
[ 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
}
}
}
[;]
これは、そこで利用可能な他のすべての RDBMS に適用できるはずです。すべての製品 IMO のすべての構文を覚えても意味がありません。
select *
into tmp
from orders
良さそうに見えますが、tmp が存在しない場合にのみ機能します (作成して塗りつぶします)。(SQL サーバー)
既存の tmp テーブルに挿入するには:
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