首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将一个表插入到另一个具有冲突的自动增量值的表中的最简单方法?

将一个表插入到另一个具有冲突的自动增量值的表中的最简单方法?
EN

Stack Overflow用户
提问于 2017-12-02 02:27:04
回答 2查看 38关注 0票数 0

我有两个表,它们有一个很大的列列表。它们都是相同的结构,但不同的数据。但是,这两个表都有一个可能相似的索引/自动增量列。有没有一种简单的方法来运行这样的命令:

代码语言:javascript
运行
复制
insert into table1 (select * from table2);

并让插入忽略表2中的自动增量列?为了避免在表1和表2的索引列中有相似的值时出现错误?我希望复制所有内容,并对表1中的表2数据进行新的自动递增。

或者,我并不关心自动增量索引的值是什么。如果有一种方法可以合并这两个表,然后重新生成唯一的AI列,那么也可以。

我知道我可以通过在两个表中分别指定每个字段并省略自动增量列来解决这个问题。我只是想知道有没有更简单的方法?如果没有,有没有一种简单的方法来生成字段列表/语句?

EN

回答 2

Stack Overflow用户

发布于 2017-12-02 02:51:05

这是目前我所知道的最有效的方法。假设is索引名为"recno“

代码语言:javascript
运行
复制
ALTER TABLE table1 DROP COLUMN recid;
ALTER TABLE table2 DROP COLUMN recid;
insert into table1 (select * from table2);
ALTER TABLE table1 ADD `recid` INT NOT NULL AUTO_INCREMENT [AFTER `column`], ADD PRIMARY KEY (`recid`);
ALTER TABLE table2 ADD `recid` INT NOT NULL AUTO_INCREMENT [AFTER `column`], ADD PRIMARY KEY (`recid`);
票数 0
EN

Stack Overflow用户

发布于 2017-12-02 03:25:23

真的没有办法做到这一点。SELECT列表中的*表示按顺序排列的“所有列”。满足指定条件的列也不例外。

对于我们要插入的省略的列的列表也是如此...这是所有的列。

实现指定目标的最有效方法(就数据库资源而言)是列出列,并从列表中省略auto_increment列。

代码语言:javascript
运行
复制
INSERT INTO t (b,c,d,e) SELECT b,c,d,e FROM s ; 

我们可以从information_schema.columns获取表的列名列表...

例如,要获取table2中的列名列表:

代码语言:javascript
运行
复制
SELECT c.column_name
  FROM information_schema.columns c
 WHERE c.table_schema = 'mydatabase'
   AND c.table_name   = 'table2'
 ORDER
    BY c.ordinal_position

要从列表中排除auto_increment列,我们可以添加一个WHERE子句,它根据列的名称排除该列

代码语言:javascript
运行
复制
 WHERE c.column_name NOT IN ('my_autoincrement_column_name') 

或者我们可以检查出现在EXTRA列中的'auto_increment'

代码语言:javascript
运行
复制
 WHERE c.extra NOT LIKE '%auto_increment%'

要获得两个表中每个表的列列表(不包括auto_increment列),我们可以这样做:

代码语言:javascript
运行
复制
SET group_concat_max_len = 16777216 ;

SELECT GROUP_CONCAT( CONCAT('`',c.column_name,'`') 
         ORDER BY c.ordinal_position
         SEPARATOR ','
       ) AS `-- column_list`
  FROM information_schema.columns c
 WHERE c.table_schema = 'mydatabase'
   AND c.table_name IN ('table1','table2')
   AND c.extra NOT LIKE '%auto_increment%'
 GROUP
    BY c.table_schema
     , c.table_name
 ORDER
    BY c.table_schema
     , c.table_name

编辑

我会使用列列表,并构建一个SQL查询。

如果我们要对table2进行更改(删除auto_increment列,就像这个问题的另一个答案所建议的那样),并且如果我们不需要保留列中的值,最简单的更改将是将该列中的所有值都设置为NULL。

无需修改table1。

我们可以从table2中的列中删除auto_increment属性(如果指定了,还可以删除NOT null约束),并将该列设置为NULL。假设ai是auto_increment列的名称,并将其声明为INT UNSIGNED数据类型,我们可以这样做:

代码语言:javascript
运行
复制
 ALTER TABLE `table2` CHANGE `ai` `ai` INT UNSIGNED COMMENT '' ;
 UPDATE `table2` SET `ai` = NULL ;

然后我们可以做一个INSERT INTO table1 SELECT * FROM table2

然后将auto_increment属性重新添加到table2中的列。

这种方法比单个INSERT ... SELECT更昂贵(就数据库资源而言)。

生成一个列列表是一个额外的步骤,但是产生的操作将更加高效。我们可以仅从源表中生成一个列的列表,然后将列名替换为文字空值...

代码语言:javascript
运行
复制
INSERT INTO t SELECT NULL,b,c,d FROM s;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47599402

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档