回答:
使用INSERT ... SELECT
:
insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1
はc1, c2, ...
を除くすべての列id
です。id
of 2で明示的に挿入する場合は、それをINSERT列リストとSELECTに含めます。
insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1
id
もちろん、2番目のケースでは2の重複の可能性に注意する必要があります。
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レコードを複製する方法も参照してください
利点:
your_table
1つのアトミック操作で挿入されます。Error Code: 1113. A table must have at least 1 column
。
SET id=NULL
、エラーが発生する可能性がありますColumn 'id' cannot be null
。置き換える必要がありますUPDATE temp_table SET id = (SELECT MAX(id) + 1 as id FROM your_table);
テーブルがあると言いますuser(id, user_name, user_email)
。
次のクエリを使用できます。
INSERT INTO user (SELECT NULL,user_name, user_email FROM user WHERE id = 1)
Result: near "SELECT": syntax error
これは役立ち、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;
列に名前を付ける必要がない迅速でクリーンなソリューションの場合は、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
免責事項:この解決策は、多くの場合、多くのテーブルで行を繰り返し複製する人のみを対象としています。悪意のあるユーザーの手に渡ると危険です。
自動インクリメントする列の値として「0」を渡すこともできます。レコードが作成されるときに正しい値が使用されます。これは一時テーブルよりもはるかに簡単です。
ソース: MySQLでの行のコピー (TRiGによる2番目のコメント、Loreによる最初のソリューションへのコメントを参照)
ここにはたくさんの素晴らしい答えがあります。以下は、開発中のWebアプリに対してこのタスクを実行するために作成したストアドプロシージャのサンプルです。
-- 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
insert into MyTable(field1, field2, id_backup)
select field1, field2, uniqueId from MyTable where uniqueId = @Id;
同じ機能を探していましたが、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);
私はムーが短すぎるもののバリエーションを投稿する傾向があります:
INSERT INTO something_log
SELECT NULL, s.*
FROM something AS s
WHERE s.id = 1;
テーブルに同一のフィールドがある限り(ログテーブルの自動インクリメントを除く)、これは適切に機能します。
私は可能な限りストアドプロシージャを使用するため(データベースに精通していない他のプログラマーの作業を楽にするため)、これにより、新しいフィールドをテーブルに追加するたびに手順に戻って更新しなければならないという問題が解決します。
また、テーブルに新しいフィールドを追加すると、データベースクエリを更新する必要なく、ログテーブルにすぐに表示されるようになります(もちろん、フィールドを明示的に設定している場合を除きます)。
警告:両方のテーブルに新しいフィールドを同時に追加して、フィールドの順序が同じになるようにする必要があります。そうしないと、奇妙なバグが発生し始めます。あなたがデータベースインターフェースを書く唯一の人であり、あなたが非常に注意しているなら、これはうまくいきます。それ以外の場合は、すべてのフィールドに名前を付けます。
注:考え直してください。ソロプロジェクトで作業している場合を除いて、他の人がすべてのフィールド名を明示的にリストすることに専念し、スキーマの変更に応じてログステートメントを更新することはありません。このショートカットは、おそらくそれが引き起こす長期的な頭痛の種には値しません...特に本番システムでは。
INSERT INTO `dbMyDataBase`.`tblMyTable` ( `IdAutoincrement`、 `Column2`、 `Column3`、 `列4` ) 選択する ヌル、 `Column2`、 `Column3`、 'CustomValue' AS列4 FROM `dbMyDataBase`.`tblMyTable` WHERE `tblMyTable`.`Column2` = 'UniqueValueOfTheKey' ; / * mySQL 5.6 * /