INSERT INTO
別のテーブルからの入力を使用してテーブルを作成しようとしています。これは多くのデータベースエンジンで完全に実現可能ですが、私は常にSQL
、その日のエンジン(MySQL、Oracle、SQL Server、Informix、およびDB2)の正しい構文を覚えるのに苦労しているようです。
基になるデータベースを気にせずに値を挿入できるSQL標準(SQL-92など)に由来する銀の弾丸構文はありますか?
INSERT INTO
別のテーブルからの入力を使用してテーブルを作成しようとしています。これは多くのデータベースエンジンで完全に実現可能ですが、私は常にSQL
、その日のエンジン(MySQL、Oracle、SQL Server、Informix、およびDB2)の正しい構文を覚えるのに苦労しているようです。
基になるデータベースを気にせずに値を挿入できるSQL標準(SQL-92など)に由来する銀の弾丸構文はありますか?
回答:
Claude Houleの答え:正常に動作するはずです。また、複数の列やその他のデータも持つことができます。
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でも動作するはずです。
INSERT
別のテーブルから複数値の1つの値のみを取得するために、SQLite3で次のようにしました。
INSERT INTO column_1 ( val_1, val_from_other_table )
VALUES('val_1', (SELECT val_2 FROM table_2 WHERE val_2 = something))
私が見ている答えはどちらもInformixで特にうまく機能し、基本的には標準SQLです。つまり、表記:
INSERT INTO target_table[(<column-list>)] SELECT ... FROM ...;
Informixで問題なく動作し、すべてのDBMSで動作することを期待しています。(かつて5年以上前、これはMySQLが常にサポートしていなかった種類のことです。現在、この種の標準SQL構文はきちんとサポートされており、AFAIKはこの表記で問題なく動作します。)列リストオプションですが、ターゲット列を順番に示します。そのため、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」になります。所有者名を二重引用符で囲むと、区切り識別子のように機能します。標準SQLでは、区切り識別子は多くの場所で使用できます。Informixでは、所有者名の前後でのみ使用できます-他のコンテキストでは、Informixは、単一引用符付き文字列を文字列として、二重引用符付き文字列を区切り識別子として分離するのではなく、文字列として扱います。(もちろん、完全を期すために、任意の値に設定できる環境変数DELIMIDENTがありますが、Yが最も安全です-二重引用符は常に区切り識別子を囲み、単一引用符は常に文字列を囲んでいることを示します。)
MS SQL Serverは、角かっこで囲まれた[区切り識別子]を管理することに注意してください。それは私には奇妙に見え、確かにSQL標準の一部ではありません。
最初の回答に何かを追加するには、別のテーブルからのレコードがほんの少しだけ必要な場合(この例では1つだけ):
INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3, COLUMN4)
VALUES (value1, value2,
(SELECT COLUMN_TABLE2
FROM TABLE2
WHERE COLUMN_TABLE2 like "blabla"),
value4);
selectサブクエリを使用して挿入する2つの方法。
SELECTサブクエリ返す結果1.アプローチ一行。
INSERT INTO <table_name> (<field1>, <field2>, <field3>)
VALUES ('DUMMY1', (SELECT <field> FROM <table_name> ),'DUMMY2');
この場合、SELECTサブクエリは、WHERE条件またはSUM、MAX、AVGなどのSQL集計関数に基づいて、結果の1行のみを返すと想定しています。
2. 複数行の結果を返すSELECTサブクエリを使用する方法。
INSERT INTO <table_name> (<field1>, <field2>, <field3>)
SELECT 'DUMMY1', <field>, 'DUMMY2' FROM <table_name>;
2番目のアプローチは、どちらの場合でも機能します。
これは、selectで値を使用する別の例です。
INSERT INTO table1(desc, id, email)
SELECT "Hello World", 3, email FROM table2 WHERE ...
テーブルの列シーケンスがわかっている場合の簡単な挿入:
Insert into Table1
values(1,2,...)
列に言及する単純な挿入:
Insert into Table1(col2,col4)
values(1,2)
テーブル(#table2)の選択された列の数が挿入テーブル(Table1)と等しい場合の一括挿入
Insert into Table1 {Column sequence}
Select * -- column sequence should be same.
from #table2
テーブル(table1)の目的の列にのみ挿入する場合の一括挿入:
Insert into Table1 (Column1,Column2 ....Desired Column from Table1)
Select Column1,Column2..desired column from #table2
from #table2
次に、複数のテーブルを使用してソースを取得する別の例を示します。
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;
SELECT句の括弧をINSERTに使用するだけです。たとえばこのように:
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'
);
複数のテーブルから挿入する方法は次のとおりです。この特定の例は、多対多のシナリオでマッピングテーブルがある場合です。
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以外のものとの照合が必要です。)
Microsoft SQL Serverについては、MSDNで提供されている構文の解釈について学習することをお勧めします。Googleでは、構文を探すのがこれまでになく簡単になりました。
この特定のケースでは、
Google:site: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のすべての構文を覚えておく意味はありません。
INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT COLUMN_NAME
FROM ANOTHER_TABLE_NAME
WHERE CONDITION;
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
INSERT VALUESルートを使用して複数の行を挿入する場合は、括弧を使用してVALUESをセットに区切るようにしてください。
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');
それ以外の場合、MySQLオブジェクトは「列数が行1の値数と一致しない」ため、最終的にそれについて何をすべきかを理解すると、簡単な投稿が作成されます。
列名を書き込まずにデータをテーブルに挿入する場合。
INSERT INTO CUSTOMER_INFO
(SELECT CUSTOMER_NAME,
MOBILE_NO,
ADDRESS
FROM OWNER_INFO cm
WHERE ID>100)
テーブルは次のとおりです。
CUSTOMER_INFO || OWNER_INFO
----------------------------------------||-------------------------------------
CUSTOMER_NAME | MOBILE_NO | ADDRESS || CUSTOMER_NAME | MOBILE_NO | ADDRESS
--------------|-----------|--------- || --------------|-----------|---------
A | +1 | DC || B | +55 | RR
結果:
CUSTOMER_INFO || OWNER_INFO
----------------------------------------||-------------------------------------
CUSTOMER_NAME | MOBILE_NO | ADDRESS || CUSTOMER_NAME | MOBILE_NO | ADDRESS
--------------|-----------|--------- || --------------|-----------|---------
A | +1 | DC || B | +55 | RR
B | +55 | RR ||
Informixでは、クロードが言ったように機能します。
INSERT INTO table (column1, column2)
VALUES (value1, value2);
Postgresは次をサポートしています。select* from company.monitorとして表company.monitor2を作成します。