프로 - sql insert select from




삽입 할 값...(SELECT... FROM...) (15)

다른 테이블의 입력을 사용하여 테이블에 INSERT INTO 하려고합니다. 이것은 많은 데이터베이스 엔진에서 전적으로 가능하지만 항상 SQL 엔진 ( MySQL , Oracle , SQL Server , InformixDB2 )의 올바른 구문을 기억하는 데 어려움을 겪고 있습니다.

기본 데이터베이스에 대해 걱정하지 않고 값을 삽입 할 수있는 SQL 표준 (예 : SQL-92 )에서 제공되는 은색 글 머리 기호 구문이 있습니까?


@ Shadow_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에서도 작동 할 것이라고 지적했습니다.


Informix에서 특히 잘 보이는 응답과 기본적으로 표준 SQL입니다. 즉, 표기법 :

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

Informix와 잘 작동하며 모든 DBMS가 기대됩니다. (5 년 또는 그 전에, 이것은 MySQL이 항상 지원하지는 않았던 일종의 표준 SQL 문법이며 AFAIK는이 표기법에서 정상적으로 작동합니다.) 열 목록 선택적이지만 대상 열을 순서대로 나타내므로 SELECT 결과의 첫 번째 열이 첫 번째 나열 열로 이동합니다. 열 목록이 없으면 SELECT 결과의 첫 번째 열이 목표 테이블의 첫 x 째 컬럼.

시스템마다 다를 수있는 것은 서로 다른 데이터베이스의 테이블을 식별하는 데 사용되는 표기법입니다. 표준은 데이터베이스 간 (DBMS는 제외) 작업에 대해서는 아무런 언급이 없습니다. Informix를 사용하면 다음 표기법을 사용하여 테이블을 식별 할 수 있습니다.

[dbase[@server]:][owner.]table

즉, 현재 서버에없는 경우 해당 데이터베이스를 호스트하는 서버를 선택적으로 식별하고 선택적 소유자, 점 및 마지막으로 실제 테이블 이름을 지정하여 데이터베이스를 지정할 수 있습니다. SQL 표준은 Informix가 소유자를 호출하는 용어에 대해 스키마라는 용어를 사용합니다. 따라서 Informix에서 다음 표기법 중 하나를 사용하여 표를 식별 할 수 있습니다.

table
"owner".table
dbase:table
dbase:owner.table
[email protected]:table
[email protected]: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 표준의 일부는 아닙니다.


다른 테이블에서 다중 값 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))

다른 테이블에서 여러 레코드를 삽입하는 가장 좋은 방법입니다.

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 TABLE_NAME
SELECT COL1, COL2 ...
FROM TABLE_YOU_NEED_TO_TAKE_FROM
;

필자가 사용한 모든 데이터베이스는 DB2 , SQL Server , MY SQL , PostgresQL 구문을 따릅니다.


사실 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 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 이외의 다른 항목과 일치해야합니다.)


여러 행을 삽입하기 위해 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');

그렇지 않으면 "열 개수가 행 1의 값 개수와 일치하지 않습니다"라는 MySQL 객체가 생기면 마지막으로 수행 할 작업을 파악할 때 사소한 게시물을 작성하게됩니다.


첫 번째 응답에 무언가를 추가하려면 다른 테이블의 레코드를 몇 개만 필요로 할 때 (이 예제에서는 하나만) :

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

테이블 열 순서를 알고있을 때 간단한 삽입 :

    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 질의의 VALUES 부분 대신에 아래와 같이 SELECT 질의를 사용하면된다.

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

SELECT * INTO 테이블을 사용하여 모든 열을 삽입하려는 경우이 방법을 사용할 수 있습니다.

SELECT  *
INTO    Table2
FROM    Table1;

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 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




ansi-sql-92