MySQL: как копировать строки, но изменить несколько полей?
У меня есть большое количество строк, которые я хотел бы скопировать, но мне нужно изменить одно поле.
Я могу выбрать строки, которые я хочу скопировать:
select * from Table where Event_ID = "120"
Теперь я хочу скопировать все эти строки и создать новые строки при настройке Event_ID
в 155
, Как я могу сделать это?
8 ответов
INSERT INTO Table
( Event_ID
, col2
...
)
SELECT "155"
, col2
...
FROM Table WHERE Event_ID = "120"
Здесь col2, ... представляют оставшиеся столбцы (кроме Event_ID) в вашей таблице.
Это решение, при котором у вас в таблице много полей, и вы не хотите, чтобы все поля печатались пальцами, просто введите нужные:)
Как скопировать несколько строк в одну и ту же таблицу, где некоторые поля имеют разные значения:
- Создайте временную таблицу со всеми строками, которые вы хотите скопировать
- Обновите все строки во временной таблице нужными значениями.
- Если у вас есть поле с автоинкрементом, вы должны установить его в NULL во временной таблице
- Скопируйте все строки временной таблицы в исходную таблицу.
- Удалить временную таблицу
Ваш код:
CREATE table temporary_table AS SELECT * FROM original_table WHERE Event_ID="155";
UPDATE temporary_table SET Event_ID="120";
UPDATE temporary_table SET ID=NULL
INSERT INTO original_table SELECT * FROM temporary_table;
DROP TABLE temporary_table
Общий код сценария:
CREATE table temporary_table AS SELECT * FROM original_table WHERE <conditions>;
UPDATE temporary_table SET <fieldx>=<valuex>, <fieldy>=<valuey>, ...;
UPDATE temporary_table SET <auto_inc_field>=NULL;
INSERT INTO original_table SELECT * FROM temporary_table;
DROP TABLE temporary_table
Упрощенный / сжатый код:
CREATE TEMPORARY TABLE temporary_table AS SELECT * FROM original_table WHERE <conditions>;
UPDATE temporary_table SET <auto_inc_field>=NULL, <fieldx>=<valuex>, <fieldy>=<valuey>, ...;
INSERT INTO original_table SELECT * FROM temporary_table;
В качестве создания временной таблицы используется TEMPORARY
Ключевое слово будет автоматически удалено после завершения сеанса (как предложено @ar34z).
Допустим, в вашей таблице есть два других столбца: foo и bar
INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, "155"
FROM Table
WHERE Event_ID = "120"
Если у вас есть множество столбцов в вашей таблице и вы не хотите печатать каждый из них, вы можете сделать это, используя временную таблицу, например;
SELECT *
INTO #Temp
FROM Table WHERE Event_ID = "120"
GO
UPDATE #TEMP
SET Column = "Changed"
GO
INSERT INTO Table
SELECT *
FROM #Temp
Эй, как насчет копирования всех полей, измените одно из них на одно и то же значение + что-то еще.
INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, Event_ID+"155"
FROM Table
WHERE Event_ID = "120"
??????????
Пока Event_ID является Integer, делайте это:
INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, (Event_ID + 155)
FROM Table
WHERE Event_ID = "120"
Добавление к ответу @DaveTheBFG: если у вас есть столбец идентификаторов («Table_PK» в приведенном ниже примере), строка INSERT завершится ошибкой, но вы можете сделать следующее (зависит от SQL Server, но концепция может применяться к другим базам данных. ):
SELECT *
INTO #Temp
FROM Table WHERE Event_ID = "120"
UPDATE #TEMP
SET Column = "Changed"
ALTER TABLE #TEMP DROP COLUMN Table_PK
EXEC sp_executesql N'INSERT INTO Table SELECT * FROM #Temp'
Если вы не возражаете сделать это в своем коде, это намного проще сделать. Например, в php вы можете сделать
function copyQuery($table, $row){
$queryColumns = $queryValues = '';
foreach ($row as $key => $value) {
$queryColumns .= $key.', ';
$queryValues .= "'$value', ";
}
$queryColumns = rtrim($queryColumns, ', ');
$queryValues = rtrim($queryValues, ', ');
return "INSERT INTO $table ($queryColumns) VALUES ($queryValues)";
}
$records = mysqli_query($connect, "SELECT * FROM Table WHERE Event_ID = 120");
while ($row = mysqli_fetch_assoc($records)) {
unset($row['id']);
$row['Event_ID'] = 155;
$query = copyQuery('Table', $row);
mysqli_query($connect, $query);
}
Использование функции необязательно. Я сделал это, потому что мне нужно было сделать это несколько раз. Я использовал эту опцию, потому что теперь я могу забыть об этом, если столбцы базы данных изменятся в будущем.