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

时间:2017-12-01 18:27:04

标签: mysql mariadb

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

insert into table1 (select * from table2);

并让插入忽略表2中的自动增量列?如果表1和表2的索引列中有类似值,则要避免错误?我想复制所有内容,并为表1中的表2数据提供新的自动增量。

或者,我不关心自动增量索引的值。如果有办法合并两个表,然后重新生成也可以工作的唯一AI列。

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

2 个答案:

答案 0 :(得分:0)

这是我现在所知道的最有效的方法。假设A.I. index被称为" recno"

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

答案 1 :(得分:0)

这不是真正的方法。 SELECT列表中的*表示"所有列"在顺序位置。符合指定条件的列也不例外。

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

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

INSERT INTO t (b,c,d,e) SELECT b,c,d,e FROM s ; 

我们可以从information_schema.columns ...

获取表格的列名列表

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

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子句,用它排除该列的名称

 WHERE c.column_name NOT IN ('my_autoincrement_column_name') 

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

 WHERE c.extra NOT LIKE '%auto_increment%'

要获取两个表中每个表的列列表(不包括auto_increment列),我们可以执行以下操作:

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数据类型,我们可以这样做:

 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相比,这种方法(就数据库资源而言)更为昂贵。

生成列列表是一个额外的步骤,但结果操作会更有效。我们可以从源表生成列列表,然后用文字NULL值替换列名...

INSERT INTO t SELECT NULL,b,c,d FROM s;