MySQL: как копировать строки, но изменить несколько полей?

195

У меня есть большое количество строк, которые я хотел бы скопировать, но мне нужно изменить одно поле.

Я могу выбрать строки, которые я хочу скопировать:

select * from Table where Event_ID = "120"

Теперь я хочу скопировать все эти строки и создать новые строки при установке Event_IDв 155. Как я могу сделать это?

Андрей
источник

Ответы:

279
INSERT INTO Table
          ( Event_ID
          , col2
           ...
          )
     SELECT "155"
          , col2
           ...
      FROM Table WHERE Event_ID = "120"

Здесь col2, ... представляют остальные столбцы ( кроме Event_ID) в вашей таблице.

DCP
источник
39
Есть ли способ сделать это без указания имен столбцов?
Андрей
4
Не то, чтобы я знал. Конечно, если ваша таблица имеет около 1000 столбцов или что-то в этом роде, и вы не хотите вводить их все, тогда вы можете написать SQL-оператор для построения SQL-оператора :). То, как вы это сделаете, будет использовать information_schema, чтобы получить имена столбцов для таблицы. Но это действительно излишне, я бы просто напечатал названия столбцов.
2010 года
3
Возможно ли это, используя звездочку, чтобы получить оставшиеся столбцы?
Питер
2
Войдите в систему, чтобы проголосовать, чтобы узнать, за что я уже проголосовал. Я думаю, это спасло меня несколько раз :) Спасибо!
aexl
2
@Bitterblue - Извините, я не понимаю ваш комментарий. Я никогда не говорил, что col2 ... были столбцами, которые вы не хотите копировать, я просто сказал, что они представляют остальные столбцы таблицы. Очевидно, что они будут скопированы, иначе их вообще не будет в операторе SQL.
DCP
141

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

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

  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).

Алекс Христодулу
источник
7
MySQL поддерживает TEMPORARYключевое слово для создания временных таблиц. Использование CREATE TEMPORARY TABLEавтоматически удалит таблицу, когда сессия (серия SQL-запросов) будет завершена. Отбрасывать таблицу не нужно, и она не конфликтует с другими временными таблицами с тем же именем. (например, при живом взломе (что я бы не рекомендовал))
ar34z
1
этот код работает только в том случае, если вы используете #teilitary_table вместо временного_таблицы, может быть, проблема MSSQL?
TruthOf42
16
В принципе, это отлично сработало, но мне пришлось преодолеть ограничение Not Null на первичный ключ во временной таблице, которая, кажется, скопирована из исходной таблицы. Я исправил это, изменив временную таблицу перед обновлением следующим образом: ALTER TABLE temporary_table MODIFY <auto_inc_not_null_field> INT; Тогда обновление первичного ключа до Null не завершится ошибкой.
Сноррис
1
Я не могу заставить его работать в PostgreSQL 9.4: Exception: null value in column <auto_inc_not_null_field> violates not-null constraint. Я пробовалALTER TABLE temporary_table ALTER COLUMN <auto_inc_not_null_field> DROP NOT NULL;
n1000
1
Я тестировал с различными версиями MySQL и MariaDB. Идеально подходит для меня, и я предпочитаю эту версию принятому ответу, что на самом деле здесь происходит довольно часто :)
hexerei software
41

Допустим, в вашей таблице есть два других столбца: foo и bar

INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, "155"
  FROM Table
 WHERE Event_ID = "120"
Питер Бейли
источник
4
Есть ли способ сделать это без указания имен столбцов?
Андрей
@PeterBailey Новичок в MySQL, не могли бы вы пролить свет на то, как работает код: /
3kstc
10

Если у вас есть множество столбцов в вашей таблице и вы не хотите печатать каждый из них, вы можете сделать это, используя временную таблицу, например;

SELECT *
INTO #Temp
FROM Table WHERE Event_ID = "120"
GO

UPDATE #TEMP
SET Column = "Changed"
GO

INSERT INTO Table
SELECT *
FROM #Temp
Davethebfg
источник
6
примечание: это предполагает, что у вас нет первичного ключа в вашей таблице
kommradHomer
2

Эй, как насчет копирования всех полей, измените одно из них на одно и то же значение + что-то еще.

INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, Event_ID+"155"
  FROM Table
 WHERE Event_ID = "120"

??????????

Димитар
источник
0

Пока Event_ID является Integer, делайте это:

INSERT INTO Table (foo, bar, Event_ID)
SELECT foo, bar, (Event_ID + 155)
  FROM Table
WHERE Event_ID = "120"
axel.becker
источник