INSERT에서 자동 증분 키를 처리하는 방법 (SELECT * FROM…)


13

나는이 table1table2MySQL을한다. 둘 다 기본 auto_increment키가 id있습니다.

테이블 스키마가 일치하고에 INSERT INTO table1 (SELECT * FROM table2)삽입 된 새 행과 관련하여 어떤 일이 발생 table1합니까? id행의 값 table1이 같으면 이전 값 을 유지하고 충돌을 생성 id합니까? auto_increment에 의해 새로운 값이 생성됩니까? 스토리지 엔진 또는 잠금에 의존합니까?

답변:


13

자동 증분 열에 삽입하고 값을 지정할 수 있습니다. 이건 괜찮아; 자동 증분 생성기를 무시합니다.

NULL 또는 0 또는 값을 삽입하려고 DEFAULT하거나 INSERT 문의 열에서 자동 증가 열을 생략하면 자동 증가 생성기가 활성화됩니다.

따라서 INSERT INTO table1 SELECT * FROM table2괄호가 필요하지 않습니다. 의 id 값이 있음을이 방법 table2그대로 복사되며, table1없는 새 값을 생성합니다.

당신이 경우 원하는 table1 새로운 가치를 생성하기 위해, 당신은 할 수 없다 SELECT *. id 열에 null 또는 0을 사용하십시오.

INSERT INTO table1 SELECT 0, col1, col2, col3, ... FROM table2;

또는 INSERT 문의 열 목록과 SELECT 문의 선택 목록에서 열을 생략합니다.

-- No id in either case:
INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3, ... FROM table2;

묻기 전에 "select * one column을 제외하고"에 대한 구문이 SQL에 없습니다. 삽입하려는 열 이름의 전체 목록을 작성해야합니다.


0을 값으로 삽입하는 것을 허용 / 금지하는 옵션이 없습니까? (두 번째 단락에 관하여)
Sascha Rambeaud

1
예, SQL_MODE = NO_AUTO_VALUE_ON_ZERO 이면 AI 열에 리터럴 0 값을 삽입 할 수 없습니다. 이 SQL 모드를 사용하는 경우 NULL은 여전히 ​​AI 생성기를 활성화하거나 열을 생략해도 작동합니다.
Bill Karwin

@BillKarwin, 마지막 단락과 관련하여 subresult를 얻은 후 select * from table첫 번째 열을 제거하기 위해이 subresult를 조작 할 방법이 없습니까?
Pacerier

@Pacerier, 내가 올바르게 이해하면 select *의미 할 수 있는지 묻습니다 select * except for the first column. 대답은 '아니오. select *항상 해당 테이블에서 모든 열을 요청 합니다. 부분 집합을 원하면 원하는 열을 철자해야합니다.
Bill Karwin 2019

@BillKarwin, 흠, 나는 수직 where 절을 수행하기 위해 테이블 을 피벗 한 다음 예를 들어 select*from transpose(select*from(transpose(select*from table where Id=1))where col_name<>Id)또는 더 간결하게 다시 피벗하려고 select*from table where Id=1 and $col<>Id생각했습니다. 어떻게 생각하십니까?
Pacerier

3

선택의 id는 테이블에 삽입 된 것과 동일한 값이됩니다. 기존 행을 복제하려고하면 오류가 발생합니다.

Bill Karwin : 문의하기 전에 "select * 하나의 열을 제외하고"에 대한 구문은 SQL에 없습니다.

이것은 몇 가지 창의력으로 달성 할 수 있습니다.

SET @sql = CONCAT('INSERT INTO <table> SELECT null, 
    ', (SELECT GROUP_CONCAT(COLUMN_NAME) 
    FROM information_schema.columns 
    WHERE table_schema = '<database>' 
    AND table_name = '<table>' 
    AND column_name NOT IN ('id')), ' 
from <table> WHERE id = <id>');  

PREPARE stmt1 FROM @sql;
EXECUTE stmt1;

그러면 새 행이 선택한 행의 ID 대신 자동 증분 ID를 얻습니다.


2
영리하지만 나에게 그것은 삽입하려는 열 이름의 전체 목록을 철자하는 것으로 계산됩니다.
Bill Karwin

1
글쎄 mysql은 자동으로 철자를 쓰는 것과 수동으로하는 것입니다. 열이 많은 테이블이 있으면 누락되거나 철자가 틀리는 것을 방지 할 수 있습니다.
curmil
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.