MySQL:如何复制行,但要更改一些字段?


194

我要复制很多行,但是我需要更改一个字段。

我可以选择要复制的行:

select * from Table where Event_ID = "120"

现在,我想复制所有的行而设置创建新行Event_ID155。我该怎么做?

Answers:


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

在这里,col2,...代表表中的其余列(Event_ID 以外的列)。


39
有什么方法可以不必指定列名呢?
安德鲁(Andrew)2010年

4
不是我知道的。当然,如果您的表有1000列之类的东西,并且您不想全部键入它们,那么您可以编写一条SQL语句来构建您的SQL语句:)。您将执行的方式是使用information_schema获取表的列名。但这实在太过分了,我只想输入列名。
dcp 2010年

3
使用星号来获取剩余的列是否可能?
彼得

2
登录进行投票只是为了发现我已经对此进行了投票。我想这已经为我节省了很多时间:)谢谢!
aexl

2
@Bitterblue-对不起,我不明白您的评论。我从未说过col2,...是您不想复制的列,我只是说它们代表表中剩余的列。很明显,它们将被复制,否则,它们将根本不在SQL语句中。
dcp dcp

139

这是一个解决方案,您的表中有许多字段,不想输入所有字段都变得抽筋,只需输入所需的字段即可:)

如何将某些行复制到同一表中,而某些字段具有不同的值:

  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 2014年

1
此代码仅在您使用#temporary_table而不是temporary_table时才有效,也许是MSSQL问题?
TruthOf42 2014年

16
这对我来说基本上是完美的,但是我确实必须克服对临时表中主键的Not Null约束,该约束似乎是从原始表中复制的。我通过在更新之前按如下方式修改临时表来解决此问题:ALTER TABLE temporary_table MODIFY <auto_inc_not_null_field> INT; 将主键更新为Null不会失败。
snorris,2015年

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,2015年

1
我测试了不同的MySQL和MariaDB版本。对我来说完美的作品,我更喜欢这个版本,而不是公认的答案,这实际上经常发生在这里:)
hexerei软件2016年

40

假设您的表格还有另外两列:foo和bar

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

4
有什么方法可以不必指定列名呢?
安德鲁(Andrew)2010年

@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

6
注意:这假设您的表中没有主键
kommradHomer 2014年

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"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.