MySQL에서 자동 증가 필드를 사용하여 행을 복사하고 동일한 테이블에 삽입하는 방법은 무엇입니까?


233

MySQL의에서 나는있는 행을 복사하려고 자동 증가 column ID=1삽입 을 가진 새로운 행으로 같은 테이블에 데이터를 column ID=2.

단일 쿼리로 어떻게 할 수 있습니까?

답변:


351

사용 INSERT ... SELECT:

insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1

c1, c2, ...제외한 모든 열은 어디에 있습니까 id? id를 2 로 명시 적으로 삽입하려면 INSERT 열 목록과 SELECT에 포함하십시오.

insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1

id물론 두 번째 경우에는 2 의 가능한 복제본 을 처리해야합니다.


1
INFORMATION_SCHEMA를 사용하여 프로그래밍 방식으로 열 이름을 얻을 수 있습니다 ... 하위 쿼리 및 일부 문자열 함수로 사용할 수 있는지 궁금합니다. 흠 ...
이즈미르 라미레즈

1
@ Yzmir : 동적 SQL을 사용해야하며 일반적으로 저장 프로 시저를 작성해야합니다. 어쨌든 편리한 열 이름 목록을 가져야 할 때보 다 더 많은 문제가있는 것 같습니다.
mu는 너무 짧다

6
저장 프로 시저로 이동하면 내 경험에 동의합니다. 다시 돌아 가지 않습니다. 이제 해당 데이터베이스와 결혼하여 변경하고 싶을 때마다 비용이 추가됩니다.
이즈미르 라미레즈

11
@ YzmirRamirez, 당신은 결혼이 본질적으로 나쁜 일처럼 들리게합니다. :)
Falken 교수

1
복사 된 다른 모든 필드와 함께 열에 하나의 사용자 정의 값을 추가하는 방법은 무엇입니까?
Manish Kumar

49

IMO는 가장 좋은 것은 SQL 문을 사용하여 해당 행을 복사하는 동시에 동시에 필요하고 변경하려는 열만 참조하는 것 같습니다.

CREATE TEMPORARY TABLE temp_table ENGINE=MEMORY

SELECT * FROM your_table WHERE id=1;
UPDATE temp_table SET id=NULL; /* Update other values at will. */

INSERT INTO your_table SELECT * FROM temp_table;
DROP TABLE temp_table;

av8n.com-SQL 레코드 복제 방법 도 참조하십시오.

혜택:

  • SQL 문 2는 복제 프로세스 중에 변경해야하는 필드 만 언급합니다. 그들은 다른 분야에 대해 알지 못하거나 걱정하지 않습니다. 다른 필드는 변경없이 그대로갑니다. 이는 SQL 문 작성, 읽기, 유지 보수 및 확장 성을 향상시킵니다.
  • 일반적인 MySQL 문만 사용됩니다. 다른 도구 나 프로그래밍 언어는 필요하지 않습니다.
  • your_table번의 원자 조작으로 완전히 올바른 레코드가 삽입됩니다 .

3
이 멋진 트릭 (나는 그것을 좋아했지만 나에게는 효과가 없었습니다)은 TEXT / VARCHAR 열을 포함하는 테이블에서 작동하지 않습니다. 나는 그것을 시도하고 얻었다 : (1163) : 사용 된 테이블 유형은 BLOB / TEXT 열을 지원하지 않습니다. 물론 MySQL에서의 사용은 매우 제한적입니다! 미래에는 이러한 제한이 해제되거나 다른 DB 시스템에서 작동하지만 실제로는 제한되어 있습니다.
Juergen

나는 임시 테이블을 영리하게 사용하는 것을 정말로 좋아합니다. 열이 많은 테이블에 유용합니다!
Lasma

1
멋지게 보이지만 MySQL에서 첫 번째 쿼리를 실행하면을 얻습니다 Error Code: 1113. A table must have at least 1 column.
신체적

3
많은 열에 대한 최상의 답변. 그러나 SET id=NULL오류가 발생할 수 있습니다 Column 'id' cannot be null. UPDATE temp_table SET id = (SELECT MAX(id) + 1 as id FROM your_table);
Modder

1
@physicalattraction 당신은 처음 두 줄이 하나의 진술인지 확인해야합니다.
Samuurai

16

테이블이이라고 가정하십시오 user(id, user_name, user_email).

이 쿼리를 사용할 수 있습니다 :

INSERT INTO user (SELECT NULL,user_name, user_email FROM user WHERE id = 1)

29
당신은해야한다 항상 INSERT를 사용할 때 스키마가 변경 될 때, 그렇지 않으면 당신은 이상하고 흥미로운 버그를 얻을 것이다, 열 이름을 지정합니다.
mu는 너무 짧다

2
정말 이상하고 재미 있습니다. : D
sparkyShorts

sqlite와 함께 작동하지 않습니다. Result: near "SELECT": syntax error
kyb

10

이것은 도움이되었으며 BLOB / TEXT 열을 지원합니다.

CREATE TEMPORARY TABLE temp_table
AS
SELECT * FROM source_table WHERE id=2;
UPDATE temp_table SET id=NULL WHERE id=2;
INSERT INTO source_table SELECT * FROM temp_table;
DROP TEMPORARY TABLE temp_table;
USE source_table;

이것은 다른 답변보다 어떤면에서 더 낫습니까?
Smar

3
100 개의 필드가있는 테이블이 있으면 꽤 좋습니다. ID에 대해 null이 아닌 제약 조건을 제외하고는 실패합니다
Loïc Faure-Lacroix

오류 코드 : 1136. 열 개수가 1 행의 값 개수와 일치하지 않습니다
Oleksii Kyslytsyn

열이 100 개인 테이블이있는 경우 훨씬 좋습니다.
Tyler S. Loeper 2013 년

몇 년 전에 이것이 parvus가 말한 것이 아닙니까?
ToolmakerSteve

7

열 이름을 지정할 필요가없는 빠르고 깨끗한 솔루션을 위해 https://stackoverflow.com/a/23964285/292677에 설명 된대로 준비된 명령문을 사용할 수 있습니다.

이 작업을 자주 수행 할 수 있도록 복잡한 솔루션이 필요한 경우이 절차를 사용할 수 있습니다.

DELIMITER $$

CREATE PROCEDURE `duplicateRows`(_schemaName text, _tableName text, _whereClause text, _omitColumns text)
SQL SECURITY INVOKER
BEGIN
  SELECT IF(TRIM(_omitColumns) <> '', CONCAT('id', ',', TRIM(_omitColumns)), 'id') INTO @omitColumns;

  SELECT GROUP_CONCAT(COLUMN_NAME) FROM information_schema.columns 
  WHERE table_schema = _schemaName AND table_name = _tableName AND FIND_IN_SET(COLUMN_NAME,@omitColumns) = 0 ORDER BY ORDINAL_POSITION INTO @columns;

  SET @sql = CONCAT('INSERT INTO ', _tableName, '(', @columns, ')',
  'SELECT ', @columns, 
  ' FROM ', _schemaName, '.', _tableName, ' ',  _whereClause);

  PREPARE stmt1 FROM @sql;
  EXECUTE stmt1;
END

다음과 같이 실행할 수 있습니다.

CALL duplicateRows('database', 'table', 'WHERE condition = optional', 'omit_columns_optional');

duplicateRows('acl', 'users', 'WHERE id = 200'); -- will duplicate the row for the user with id 200
duplicateRows('acl', 'users', 'WHERE id = 200', 'created_ts'); -- same as above but will not copy the created_ts column value    
duplicateRows('acl', 'users', 'WHERE id = 200', 'created_ts,updated_ts'); -- same as above but also omits the updated_ts column
duplicateRows('acl', 'users'); -- will duplicate all records in the table

면책 조항 :이 솔루션은 많은 테이블에서 행을 반복적으로 복제하는 사람에게만 적합합니다. 불량 사용자의 손에 위험 할 수 있습니다.


3

열을 자동 증가시킬 값으로 '0'을 전달할 수도 있습니다. 레코드가 작성 될 때 올바른 값이 사용됩니다. 이것은 임시 테이블보다 훨씬 쉽습니다.

출처 : MySQL에서 행 복사 (TRiG의 첫 번째 솔루션에 대한 Lore의 두 번째 주석 참조)


1
이 방법은 NULL이 허용되지 않는 경우 최신 MySQL 버전에서 작동합니다.
err

3

여기에 많은 훌륭한 답변이 있습니다. 다음은 개발중인 웹 응용 프로그램에 대해이 작업을 수행하기 위해 작성한 저장 프로 시저 샘플입니다.

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON

-- Create Temporary Table
SELECT * INTO #tempTable FROM <YourTable> WHERE Id = Id

--To trigger the auto increment
UPDATE #tempTable SET Id = NULL 

--Update new data row in #tempTable here!

--Insert duplicate row with modified data back into your table
INSERT INTO <YourTable> SELECT * FROM #tempTable

-- Drop Temporary Table
DROP TABLE #tempTable

현재 버전의 MariaDB / MySQL 설정에서 id = null은 # 1048을 제공합니다. 'id'열은 null 일 수 없으며 id = 0으로 설정하면 작동합니다.
shelbypereira

2
insert into MyTable(field1, field2, id_backup)
    select field1, field2, uniqueId from MyTable where uniqueId = @Id;

3
여기에 다른 답변보다 더 나은 방법은 무엇입니까?
Smar

1
@smar IMO는 청소기 이해의
Satbir 키라

2

MySQL Workbench를 사용할 수있는 경우 행을 마우스 오른쪽 단추로 클릭하고 '행 복사'를 선택한 다음 빈 행을 마우스 오른쪽 단추로 클릭하고 '행 붙여 넣기'를 선택한 다음 ID를 변경하여이를 수행 할 수 있습니다. '적용'을 클릭하십시오.

행을 복사하십시오.

여기에 이미지 설명을 입력하십시오

복사 한 행을 빈 행에 붙여 넣습니다.

여기에 이미지 설명을 입력하십시오

ID를 변경하십시오.

여기에 이미지 설명을 입력하십시오

대다:

여기에 이미지 설명을 입력하십시오


0

나는 같은 기능을 찾고 있었지만 MySQL을 사용하지 않습니다. 물론 기본 키 (id)를 제외한 모든 필드를 복사하고 싶었습니다. 이것은 스크립트 나 코드에서 사용되지 않는 원샷 쿼리입니다.

PL / SQL과 관련된 길을 찾았지만 다른 SQL IDE가 할 것이라고 확신합니다. 나는 기본을했다

SELECT * 
FROM mytable 
WHERE id=42;

그런 다음 찾을 수있는 SQL 파일로 내 보냅니다.

INSERT INTO table (col1, col2, col3, ... , col42) 
VALUES (1, 2, 3, ..., 42);

방금 편집하여 사용했습니다.

INSERT INTO table (col1, col2, col3, ... , col42) 
VALUES (mysequence.nextval, 2, 3, ..., 42);

0

mu가 너무 짧게 게시 된 변형을 사용하는 경향이 있습니다.

INSERT INTO something_log
SELECT NULL, s.*
FROM something AS s
WHERE s.id = 1;

테이블에 동일한 필드가있는 한 (로그 테이블의 자동 증분 제외), 잘 작동합니다.

가능하면 데이터베이스에 익숙하지 않은 다른 프로그래머가 쉽게 사용할 수 있도록 저장 프로 시저를 사용하므로 테이블에 새 필드를 추가 할 때마다 프로 시저로 돌아가서 업데이트해야하는 문제를 해결합니다.

또한 테이블에 새 필드를 추가하면 데이터베이스 쿼리를 업데이트하지 않고도 로그 테이블에 즉시 표시되기 시작합니다 (물론 필드를 명시 적으로 설정 한 경우가 아닌 한)

경고 : 필드 순서가 동일하게 유지되도록 두 테이블에 새 필드를 동시에 추가해야합니다. 그렇지 않으면 이상한 버그가 발생합니다. 데이터베이스 인터페이스를 작성하는 유일한 사람이고 매우 조심하면 잘 작동합니다. 그렇지 않으면 모든 필드의 이름을 지정하십시오.

참고 : 솔로 프로젝트에서 작업하지 않는 한 다른 프로젝트에서는 모든 필드 이름을 명시 적으로 나열하고 스키마가 변경되면 로그 문을 업데이트하는 것이 아닙니다. 이 지름길은 아마도 생산 시스템에서 발생할 수있는 장기 두통의 가치가 없을 것입니다.


0
`dbMyDataBase`에 삽입하십시오 .`tblMyTable` 
(
    `자동 증가`, 
    `열 2`, 
    `열 3`, 
    `열 4` 
) 

고르다 
    없는,  
    `열 2`, 
    `열 3`, 
    'CustomValue'AS Column4 
`dbMyDataBase`.`tblMyTable`에서 
`tblMyTable`.`Column2` = 'UniqueValueOfTheKey'위치 
; 
/ * mySQL 5.6 * /

3
좀 더 자세한 설명을 추가하거나 다른 답변으로 어떻게 확장되는지 살펴보십시오
Azsgy

-1

SQL하려는 행을 덤프 한 다음 생성 된 SQL을 사용하여 ID 열을 줄이고 다시 가져 오십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.