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) в вашей таблице.

Это решение, при котором у вас в таблице много полей, и вы не хотите, чтобы все поля печатались пальцами, просто введите нужные:)

Как скопировать несколько строк в одну и ту же таблицу, где некоторые поля имеют разные значения:

  1. Создайте временную таблицу со всеми строками, которые вы хотите скопировать
  2. Обновите все строки во временной таблице нужными значениями.
  3. Если у вас есть поле с автоинкрементом, вы должны установить его в NULL во временной таблице
  4. Скопируйте все строки временной таблицы в исходную таблицу.
  5. Удалить временную таблицу

Ваш код:

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);
}

Использование функции необязательно. Я сделал это, потому что мне нужно было сделать это несколько раз. Я использовал эту опцию, потому что теперь я могу забыть об этом, если столбцы базы данных изменятся в будущем.

Другие вопросы по тегам