insert into table select * from table where primarykey=1
我只想复制一行插入到同一个表中(即,我想复制表中的现有行)但我想这样做而不必列出“select”之后的所有列,因为这个表有列太多了 .
但是当我这样做时,我得到错误:
键1的重复条目'xxx'
我可以通过创建另一个具有相同列的表作为我要复制的记录的临时容器来处理这个问题:
create table oldtable_temp like oldtable;
insert into oldtable_temp select * from oldtable where key=1;
update oldtable_tem set key=2;
insert into oldtable select * from oldtable where key=2;
有没有更简单的方法来解决这个问题?
24 回答
我使用Leonard Challis的技术进行了一些改动:
作为临时表,永远不应该有多个记录,因此您不必担心主键 . 将其设置为null允许MySQL自己选择值,因此不存在创建重复的风险 .
如果你想要确定你只需要插入一行,你可以将LIMIT 1添加到INSERT INTO行的末尾 .
请注意,我还将主键值(在本例中为1)附加到临时表名称 .
Update 07/07/2014 - The answer based on my answer, by Grim..., is a better solution as it improves on my solution below, so I'd suggest using that.
您可以使用以下语法在不列出所有列的情况下执行此操作:
您可以决定以其他方式更改主键 .
我假设您希望新记录有一个新的
primarykey
?如果primarykey
是AUTO_INCREMENT
那么就这样做:...其中
col1, col2, col3, ...
是表中除primarykey
之外的所有列 .如果它不是
AUTO_INCREMENT
列,并且您希望能够为primarykey
选择新值,则类似:...其中
567
是primarykey
的新值 .您几乎已经使用了第一个查询,只需要指定列,这样您就可以在插入中排除主键,这将生成您可能在表上自动增加的自动增量,以便为表创建新的主键 . 条目 .
例如改变这个:
对此:
只是不要在INSERT的列列表或查询的SELECT部分中包含primarykey列 .
您也可以尝试转储表,找到insert命令并对其进行编辑:
--skip-extended-insert
每行为您提供一个插入命令 . 然后,您可以在您喜欢的文本编辑器中找到该行,解压缩命令并将主键更改为"default" .我使用Grim的技术稍作改动:如果有人在寻找这个查询是因为由于主键问题而无法进行简单的查询:
使用我的MySql安装5.6.26,密钥不可为空并产生错误:
因此,在创建临时表之后,我将主键更改为可为空 .
此过程假定:
你没有_duplicate_temp_table
你的主键是int
您可以访问create table
当然这并不完美,但在某些(可能是大多数)情况下它会起作用 .
这可以通过一些创造力来实现:
这将导致新行获得自动递增的id而不是所选行的id .
以下部分内容是从本网站收集的 . 这就是我在具有任意数量字段的表中复制记录所做的事情:
这也假设您在表的开头有一个AI字段
如果表的主键字段是自动增量字段,则可以对列使用查询 . 例如,名为
test_tbl
的表有3个字段id, name, age
.id
是主键字段和自动增量,因此您可以使用以下查询来复制该行:此查询导致重复每一行 .
如果表的主键字段不是自动增量字段,则可以使用以下方法:
此查询的结果是
id=19
的重复行作为id=20
插入 .我可能会迟到,但我有一个类似的解决方案,对我有用 .
这样我就不需要创建临时表等 . 由于行被复制到同一个表中,
Max(PK)+1
函数可以很容易地使用 .我来寻找这个问题的解决方案(忘记了语法),最后我自己创建了查询 . 有趣的是,事情有时会发生 .
问候
如果主键是自动增量,则只需指定除主键之外的每个字段 .
INSERT INTO table(field1,field2,field3) SELECT (field1,field2,field3) FROM table WHERE primarykey=1
我更新@LeonardChallis 's solution as it didn'为我工作,没有其他人 . 我删除了临时表中的
WHERE
子句和SET primaryKey = 0
,因此MySQL会自动增加primaryKey这当然要复制表中的行 all .
我只需要这样做,这是我的手动解决方案:
在 phpmyadmin 中,检查您想要的行复制
在查询结果操作底部,单击 'Export'
在下一页上检查 'Save as file' 然后单击 'Go'
使用文本编辑器打开导出的文件,找到主要字段的值并将其更改为唯一的值 .
返回 phpmyadmin 单击 'Import' 选项卡,找到要在 browse 下导入.sql文件的文件,单击 'Go' 并插入重复行 .
如果您不知道 PRIMARY 字段是什么,请回顾 phpmyadmin 页面,单击 'Structure' 选项卡,在 'Indexes' 页面底部,它将显示 'Field' 具有 'Keyname' 值 'PRIMARY' .
还有很长的路要走,但是如果你不想处理标记而只需要复制一行就可以了 .
我会在下面使用,
对于necropost感到抱歉,但这是我在google上找到的,因为我发现这有用但有问题我想为其他任何挖掘它的人做出重要修改 .
首先,我使用的是SQL Server,而不是MySQL,但我认为它的工作方式应该类似 . 我使用了Leonard Challis的解决方案,因为它最简单并满足了需求,但是这有一个问题 - 如果你只是拿PK并将其递增1然后如果你添加了其他记录会发生什么,因为有问题的行被添加了 . 我决定最好让系统处理PK的自动增量,所以我做了以下事情:
我相信这在MySQL中会有类似的作用,但我无法测试,对不起
我知道这是一个老问题,但这是另一个解决方案:
这假设主键是自动递增的,在主表中复制一行,并使用新的主表id创建链表数据的副本 .
获取列名称的其他选项:
-SHOW COLUMNS来自
tablename
; (列名:字段)-DESCRIBE
tablename
(列名:字段)-SELECT column_name FROM information_schema.columns WHERE table_name = 'tablename'(列名:column_name)
max233肯定是在正确的轨道上,至少对于自动增量案例 . 但是,不要做ALTER TABLE . 只需将临时表中的自动增量字段设置为NULL即可 . 这将显示错误,但临时表中的所有字段的以下INSERT将发生,并且NULL自动字段将获得唯一值 .
创建一个表
插入一行
克隆行插入上面
测试
以下是我在网站上找到的答案描述如何进行上述操作1您可以在页面底部找到答案 . 基本上,您要做的是将要复制的行复制到内存中保存的临时表中 . 然后使用update更改主键号 . 然后,将其重新插入目标表 . 然后你放弃 table .
这是它的代码:
我创建了临时表rescueteam . 我复制了原始表fitnessreport4中的行 . 然后,我将临时表中的行的主键设置为null,以便我可以将其复制回原始表而不会出现Duplicate Key错误 . 我昨天晚上尝试了这段代码并且有效 .
对于一个非常简单的解决方案,您可以使用PHPMyAdmin将行导出为CSV文件,然后只需导入修改后的CSV文件 . 编辑ID / primarykey列以在导入之前不显示任何值 .
然后在页面底部:
在哪里说“导出”只是导出,然后编辑csv文件以删除primarykey值,因此它为空,然后只需将其导入数据库,将在导入时分配新的主键 .
该解决方案显示上述工作对于所选行也是完美的 . 例如,我正在为我的nice2work项目创建演示行,这很有效完善 .
具有更新字段和自动增量值的克隆行
只想发布我的PHP代码,因为我认为我收集列的方式比前面的例子更清晰 . 这也显示了如何轻松更改字段,在这种情况下添加字符串 . 但是,您也可以使用新添加的记录替换外键字段,以防您想要复制某些子记录 .