MYSQL:如何在mysql中将整个行从一个表复制到另一个表,而第二个表则有一个额外的列?


76

我有两个具有相同结构的表,只不过有一个列...表2有我要在其中插入CURRENT_DATE()的另一列

我想将所有值从table1复制到table2。

如果我用

INSERT INTO dues_storage SELECT * FROM dues WHERE id=5;

它将引发错误,指出列数的差异。

我对此有两个问题:

  1. 我该如何解决?
  2. 以及如何在同一条语句的表2中添加附加日期列(CURRENT_DATE())的值?

你可以看看这个。它在mysql中为我工作。 stackoverflow.com/questions/57168/...
Shreyo

Answers:


96

要完善Zed的答案并回答您的评论:

INSERT INTO dues_storage
SELECT d.*, CURRENT_DATE()
FROM dues d
WHERE id = 5;

参见TJ Crowder的评论


51
务必谨慎执行此操作。它确实可以工作,但是它假定两个表中的列顺序是相同的。它与列名匹配,并且会尝试强制使值适合,这可能会导致意外结果。现在,如果您的开发结构确保列顺序与最后一列相同,则这是一种方便而直接的方法,但请注意。
TJ Crowder

幸运的是顺序是相同的。即使在将来也要牢记保持结构相同。谢谢大家!
2009年

@crunchdog如果需要设置为wherelike,应该如何组织查询A.id = B.id
尤金(Eugene)

2
您甚至需要CURRENT_DATE()吗?您可以将该字段的类型设置为TimeStamp,并将默认值设置为CURRENT_TIMESTAMP。它应该将当前的DateTime填充到创建记录的时间。
Chiwda '17

53

最安全的方法是完全指定要插入和提取的列。(对于应用程序)无法保证其中任何一个都是您认为可能的顺序。

insert into dues_storage (f1, f2, f3, cd)
    select f1, f2, f3, current_date() from dues where id = 5;

如果您担心必须更改许多执行此操作的PHP页面(如您在其他答案的注释中所示),那么存储过程已经成熟。这样,您所有的PHP页面都仅使用(例如)仅要复制的ID调用存储过程,并且它控制实际的复制过程。这样,只有一个地方需要维护代码,而我认为DBMS是执行代码的正确地方。


是的..但是我才刚开始。我现在必须找出什么是存储过程,谢谢!今天还要学习一件事!
user165242

1
这是最好的答案
Mike Volmar

8
INSERT INTO dues_storage
SELECT field1, field2, ..., fieldN, CURRENT_DATE()
FROM dues
WHERE id = 5;

表中有太多字段,有没有更短的方法?如果我在那里更改表结构,我也必须记住也要更改php页面。
user165242

您可以用会费逃脱它。*
Zed在2009年

4

希望这会对某人有所帮助...这是我写的一个PHP小脚本,以防您需要复制某些列而不是其他列,并且/或者两个表中的列的顺序不同。只要这些列的名称相同,就可以使用。因此,如果表A具有[用户ID,句柄,某些内容],而表B具有[用户ID,句柄,时间戳],则您将“选择用户ID,句柄,NOW()作为来自表A的时间戳”,然后得到该结果,然后将结果作为第一个参数传递给此函数($ z)。$ toTable是要复制到的表的字符串名称,而$ link_identifier是要复制到的数据库。对于少量数据,这相对较快。不建议您在生产环境中一次尝试移动数千行以上。

 function mysql_multirow_copy($z,$toTable,$link_identifier) {
            $fields = "";
            for ($i=0;$i<mysql_num_fields($z);$i++) {
                if ($i>0) {
                    $fields .= ",";
                }
                $fields .= mysql_field_name($z,$i);
            }
            $q = "INSERT INTO $toTable ($fields) VALUES";
            $c = 0;
            mysql_data_seek($z,0); //critical reset in case $z has been parsed beforehand. !
            while ($a = mysql_fetch_assoc($z)) {
                foreach ($a as $key=>$as) {
                    $a[$key] = addslashes($as);
                    next ($a);
                }
                if ($c>0) {
                    $q .= ",";
                }
                $q .= "('".implode(array_values($a),"','")."')";
                $c++;
            }
            $q .= ";";
            $z = mysql_query($q,$link_identifier);
            return ($q);
        }

0

或者,您可以使用内部查询来执行此操作。

SQL> INSERT INTO <NEW_TABLE> SELECT * FROM CUSTOMERS WHERE ID IN (SELECT ID FROM <OLD_TABLE>);

希望这可以帮助!


0
SET @sql = 
CONCAT( 'INSERT INTO <table_name> (', 
    (
        SELECT GROUP_CONCAT( CONCAT('`',COLUMN_NAME,'`') ) 
            FROM information_schema.columns 
            WHERE table_schema = <database_name>
                AND table_name = <table_name>
                AND column_name NOT IN ('id')
    ), ') SELECT ', 
    ( 
        SELECT GROUP_CONCAT(CONCAT('`',COLUMN_NAME,'`')) 
        FROM information_schema.columns 
        WHERE table_schema = <database_name>
            AND table_name = <table_source_name>
            AND column_name NOT IN ('id')  
    ),' from <table_source_name> WHERE <testcolumn> = <testvalue>' );  

PREPARE stmt1 FROM @sql; 
execute stmt1;

当然,用实值替换<>值,并注意引号。


-3

只是想添加这个对我来说效果很好的小片段。

INSERT INTO your_target_table SELECT * FROM your_rescource_table WHERE id = 18;

虽然我很喜欢Sequel Pro,但如果您不使用它,我强烈建议您下载它...让生活变得更加轻松

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.