テーブルEgTableがあります。私がやろうとしているのは、オートインクリメント列ID = 1の行をコピーして、行と列ID = 2の同じテーブルにデータを挿入することです。
MySqlを使うこれを1回のクエリで実行する方法を教えてください。
INSERT ... SELECT
を使用してください。
insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1
c1, c2, ...
はid
を除くすべての列です。 2のid
を明示的に挿入したい場合は、それをINSERT列リストとSELECTに含めます。
insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1
2番目のケースでは、2のid
が重複している可能性があることに注意する必要があります。
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
に挿入されます。テーブルがuser(id, user_name, user_email)
だとしましょう。
あなたはこのクエリを使用することができます:
INSERT INTO user (SELECT NULL,user_name, user_email FROM user WHERE id = 1)
これにより、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による1番目の解決策への参照)
insert into MyTable(field1, field2, id_backup)
select field1, field2, uniqueId from MyTable where uniqueId = @Id;
たくさんの素晴らしい答えがここにあります。以下は、私が開発している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
私はmuが短すぎる投稿のバリエーションを使用する傾向があります。
INSERT INTO something_log
SELECT NULL, s.*
FROM something AS s
WHERE s.id = 1;
テーブルが同じフィールドを持っている限り(ログテーブルの自動インクリメントを除く)、これはうまく機能します。
私は可能な限りストアドプロシージャを使用しているので(データベースにあまり詳しくない他のプログラマの作業を楽にするため)、テーブルに新しいフィールドを追加するたびにプロシージャに戻って更新しなければならないという問題は解決します。
また、テーブルに新しいフィールドを追加した場合、データベースクエリを更新しなくてもログテーブルにすぐに表示されるようになります(もちろんフィールドを明示的に設定しているものがない限り)。
警告: フィールドの順番が同じになるように、両方のテーブルに新しいフィールドを同時に追加してください。そうしないと、奇妙なバグが発生し始めます。あなたがデータベースインターフェースを書く唯一の人であり、そしてあなたが非常に慎重であるならば、これはうまく働きます。それ以外の場合は、すべてのフィールドの命名に固執してください。
注: /考え直してください。単独のプロジェクトで作業しているのでなければ、他の人が作業していると確信している場合を除き、すべてのフィールド名を明示的にリストし、スキーマを変更してログステートメントを更新します。この近道はおそらくそれが引き起こす可能性がある長期にわたる頭痛の種にはならないでしょう…特に本番システムでは。
SQLしたい行をダンプしてから、生成されたSQLからインポートする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 'dbMyDataBase`.`tblMyTable` ( IdAutoincrement`、 `Column2`、 ` Column3`、[.____ [Column4] ) SELECT NULL、 `Column2`、 ` Column3`、[.____ 。[CustomValue] AS Column4 FROM `dbMyDataBase`.`tblMyTable` WHERE` tblMyTable`.`Column2` = 'UniqueValueOfTheKey' ; /* mySQL 5.6 */