質問

私は。。をしようとしています INSERT INTO 別のテーブルからの入力を使用するテーブル。これは多くのデータベース エンジンで完全に実現可能ですが、正しい構文を覚えるのにいつも苦労しているようです。 SQL 今日のエンジン(MySQL, オラクル, SQLサーバー, インフォミックス, 、 そして DB2).

SQL 標準に由来する特効薬の構文はありますか (たとえば、 SQL-92)これにより、基礎となるデータベースを気にせずに値を挿入できるようになりますか?

役に立ちましたか?

解決

試す:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

これは標準の ANSI SQL であり、どの DBMS でも動作します。

それは間違いなく次の場合に機能します。

  • オラクル
  • MS SQLサーバー
  • MySQL
  • ポストグレ
  • SQLite v3
  • テラデータ
  • DB2
  • サイベース
  • バーティカ
  • HSQLDB
  • H2
  • AWSレッドシフト
  • SAP ハナ

他のヒント

@シャドウx99:これで問題なく動作するはずです。また、複数の列やその他のデータを含めることもできます。

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 で動作すると指摘しました。

複数の値の中から 1 つの値だけを取得するには INSERT 別のテーブルから、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 構文は適切にサポートされており、私の知る限り、この表記法では問題なく動作します。) 列リストはオプションですが、ターゲット列を順番に示すため、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 標準の一部ではありません。

ほとんどのデータベースは基本的な構文に従います。

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

私が使用したすべてのデータベースはこの構文に従います。 DB2, SQL Server, MY SQL, PostgresQL

別のテーブルから少数のレコードだけが必要な場合(この例では 1 つだけ)、最初の回答に何かを追加するには、次のようにします。

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

これは、 INSERT INTO のすべての列に値を指定する場合の部分 SELECT 一部。

table1 に 2 つの列があるとします。このクエリは機能するはずです。

INSERT INTO table1
SELECT  col1, col2
FROM    table2

これは機能しません (値 col2 は指定されていません):

INSERT INTO table1
SELECT  col1
FROM    table2

MS SQLサーバーを使用しています。他の RDMS がどのように動作するかはわかりません。

の代わりに VALUES 一部の INSERT クエリ、使用するだけ SELECT 以下のようにクエリします。

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

これは、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;

複数のテーブルから挿入する方法は次のとおりです。この特定の例は、多対多のシナリオでマッピング テーブルがある場合です。

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 が ID 列で不明な場合は、ID 以外の照合が必要です)。

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

これはすべての DBMS で機能します

を使用してすべての列を挿入したい場合は、これを試すことができます SELECT * INTO テーブル。

SELECT  *
INTO    Table2
FROM    Table1;

これは私にとってはうまくいきました:

insert into table1 select * from table2

この文はOracleのものとは少し異なります。

Microsoft SQL Server の場合は、MSDN で提供されている構文の解釈を学ぶことをお勧めします。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 では、すべての製品のすべての構文を覚えることに意味はありません。

実際、私は 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 () セットを追加する手順が不要になり、テーブルに入れる値を選択するだけになります。

括弧を使用してください 選択する 句を 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'
);
select *
into tmp
from orders

見た目はいいですが、tmp が存在しない場合にのみ機能します (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  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;

select サブクエリを使用して挿入する 2 つのアプローチ。

  1. SELECT サブクエリを使用して結果を返す 1行.
  2. SELECT サブクエリを使用して結果を返す 複数の行.

1.結果を返す 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 番目のアプローチはどちらの場合にも機能します。

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 の値数と一致しません」と通知し、最終的にどうすればよいかを理解したときに、つまらない投稿を書くことになります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top