如何使用MySQL中的SQL将所选行从table_source
插入table_target
,其中:
id
琐碎的INSERT INTO table_target SELECT * FROM table_source
在主键的重复条目上失败。
答案 0 :(得分:18)
必须指定列名 -
INSERT INTO table_target SELECT NULL, column_name1, column_name2, column_name3, ...
FROM table_source;
只需将NULL作为自动增量ID字段的值传递。
答案 1 :(得分:17)
您可以在插入中列出所需的所有字段...选择,或者在外部使用其他内容为您构建列表。
SQL没有类似SELECT * except somefield FROM
的内容,所以你必须咬紧牙关并写出字段名称。
答案 2 :(得分:4)
乏味但安全和正确。
编写INSERT语句而不提供列列表会导致难以调试的代码,更重要的是,如果表的定义发生更改,将会破坏非常脆弱的代码。
如果你绝对不能自己编写列名,那么在代码中构建一个工具会相对容易,它会为你创建逗号分隔列表。
答案 3 :(得分:3)
当然,主键必须是唯一的。这取决于您想要实现的目标,但您可以使用已存在的主键排除行。
INSERT INTO table_target SELECT * FROM table_source
WHERE table_source.id NOT IN (SELECT id FROM table_target)
UPDATE :既然你还需要额外的行,你应该首先解决冲突,table_source是否有关系?如果没有,你可以改变这些键:
UPDATE table_source SET id = id + 1000
WHERE id IN (SELECT id FROM table_target)
1000,是一个常数,足够大,所以它们在你的桌子结束后去。
答案 4 :(得分:1)
我认为您可以使用如下语法:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;
参考:http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html 希望它有所帮助
答案 5 :(得分:1)
这是我使用'replace insert'命令进行批量更新的最终解决方案。
SET @@session.group_concat_max_len = @@global.max_allowed_packet;
SET @schema_db = 'db';
SET @tabl = 'table';
SET @cols = (SELECT CONCAT('`',GROUP_CONCAT(COLUMN_NAME SEPARATOR '`, `'), '`') FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @schema_db AND TABLE_NAME = @tabl GROUP BY TABLE_NAME);
SET @Querystr = CONCAT('REPLACE INTO ',@schema_db,'.',@tabl,' SELECT ', @cols,' FROM import.tbl_', @tabl);
PREPARE stmt FROM @Querystr;
EXECUTE stmt;
答案 6 :(得分:0)
INSERT IGNORE
只是“绕过”重复的行。
答案 7 :(得分:0)
你可以用准备好的陈述来做。
PREPARE table_target_insert FROM 'INSERT INTO table_target SELECT ? FROM table_source';
SET @cols:='';
SELECT @cols:=GROUP_CONCAT(IF(column_name = 'id','NULL',column_name) separator ",") FROM information_schema.columns WHERE table_name='table_source';
EXECUTE table_target_insert USING @cols;
答案 8 :(得分:0)
似乎无法在MySQL Prepared Statement中将列作为占位符给出。我编译了以下测试解决方案:
SET @schema_db = 'DB';
SET @table = 'table';
SET @cols = (SELECT CONCAT(GROUP_CONCAT(COLUMN_NAME SEPARATOR ', '), "\n") FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @schema_db AND TABLE_NAME = @table GROUP BY TABLE_NAME);
SET @Querystr = CONCAT('SELECT',' ', @cols,' ','FROM',' ',@schema_db,'.',@table,' ', 'Limit 5');
PREPARE stmt FROM @Querystr;
EXECUTE stmt;
答案 9 :(得分:0)
您可以使用动态查询:
expandableListDetail
答案 10 :(得分:-1)
最简单的方法是使用phpmyadmin编写列列表,然后根据需要进行更改,在下面的示例中,我想复制id = 1078的行,在此表中我有id唯一的自动增量和别名唯一。因此我创建了我的查询如下,id&别名替换为所需的值。它就像一个魅力。
INSERT INTO sy3_menu
选择1079,menutype
,title
," alias
",note
,path
,link
,type
,published
,parent_id
,level
,component_id
,checked_out
,checked_out_time
,{ {1}},browserNav
,access
,img
,template_style_id
,params
,lft
,rgt
,{{1来自home
的{{1}},其中id = 1078
或者,要自动增加id,请使用以下Join语句:
INSERT INTO language
选择*
from(SELECT MAX(client_id
+ 1)来自sy3_menu
)a
加入(选择sy3_menu
,id
," sy3_menu
",menutype
,title
,alias
,{{1 }},note
,path
,link
,type
,published
,parent_id
,level
,component_id
来自{checked_out
,checked_out_time
,browserNav
,access
,img
,template_style_id
,params
,lft
来自{ {1}}其中id = 1079)b