我有两个表,它们有一个很大的列列表。它们都是相同的结构,但不同的数据。但是,这两个表都有一个可能相似的索引/自动增量列。有没有一种简单的方法来运行这样的命令:
insert into table1 (select * from table2);
并让插入忽略表2中的自动增量列?为了避免在表1和表2的索引列中有相似的值时出现错误?我希望复制所有内容,并对表1中的表2数据进行新的自动递增。
或者,我并不关心自动增量索引的值是什么。如果有一种方法可以合并这两个表,然后重新生成唯一的AI列,那么也可以。
我知道我可以通过在两个表中分别指定每个字段并省略自动增量列来解决这个问题。我只是想知道有没有更简单的方法?如果没有,有没有一种简单的方法来生成字段列表/语句?
发布于 2017-12-02 02:51:05
这是目前我所知道的最有效的方法。假设is索引名为"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`);
发布于 2017-12-02 03:25:23
真的没有办法做到这一点。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')
或者我们可以检查出现在EXTRA
列中的'auto_increment'
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
更昂贵(就数据库资源而言)。
生成一个列列表是一个额外的步骤,但是产生的操作将更加高效。我们可以仅从源表中生成一个列的列表,然后将列名替换为文字空值...
INSERT INTO t SELECT NULL,b,c,d FROM s;
https://stackoverflow.com/questions/47599402
复制相似问题