将MySQL中的1个表合并到另一个表中

时间:2011-12-10 08:42:39

标签: mysql

好的,这就是场景:

我们有一个数据库,其中包含一个我们希望保持尽可能小的表格。我们需要根据另一个表的主键复制其中的数据。

捕获是在我们完成行(可能是每日进程)后,我们将从原始数据库中删除行,但将数据保存在新表中。

例如

表A中的10行 - > 10行复制到表B - 表B中总共10行

结束一天cron删除表A中的所有内容

表A中的10行 - > 10行复制到表B - 表B中总共20行

我的问题:有没有办法在没有A发送删除的情况下从A复制到B?

1 个答案:

答案 0 :(得分:1)

如果要删除行,我假设它们不在表A中,那么您将它们发送到表B的是什么?

如果删除您的意思是“标记为已删除”,则只需在REPLACE语句中按该条件进行过滤。

  

REPLACE的工作原理与INSERT完全相同,只是如果在一个旧行中   table与PRIMARY KEY或UNIQUE的新行具有相同的值   index,在插入新行之前删除旧行。看到   第12.2.5节“INSERT语法”。

     

REPLACE是SQL标准的MySQL扩展。它插入,   或删除和插入。对于标准的另一个MySQL扩展   插入或更新的SQL - 请参见第12.2.5.3节“INSERT ...   ON DUPLICATE KEY UPDATE语法“。

     

请注意,除非表具有PRIMARY KEY或UNIQUE索引,否则使用   REPLACE语句毫无意义。它等同于INSERT,   因为没有索引可用于确定是否有新行   复制另一个。

阅读完评论后,我明白了你的问题:

如果A有10而B有0,则首先复制B将有10而A将有0(因为你将删除它们)。

在下次复制时,A将有5并且这些将不会出现在B中,因此您只需将所有从A复制到B,因此B有15(再次A将被删除)。

但是,如果您只想从A复制行的子集,则需要先应用该过滤器(对于REPLACE)。

REPLACE将为您执行此操作 - 除了从源表中删除行,您必须手动执行此操作。它将始终保持B更新。

mysql> create table A (id INT AUTO_INCREMENT PRIMARY KEY, foo VARCHAR(12));
Query OK, 0 rows affected (0.05 sec)

mysql> create table B (id INT AUTO_INCREMENT PRIMARY KEY, foo VARCHAR(12));
Query OK, 0 rows affected (0.06 sec)

mysql> INSERT INTO A VALUES ('','One'),('','Two');
Query OK, 2 rows affected, 2 warnings (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> REPLACE INTO B SELECT * FROM A;
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM B;
+----+------+
| id | foo  |
+----+------+
|  1 | One  |
|  2 | Two  |
+----+------+
2 rows in set (0.00 sec)

mysql> UPDATE A SET `foo` = 'One-Up' WHERE `id` = 1; 
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM A;
+----+--------+
| id | foo    |
+----+--------+
|  1 | One-Up |
|  2 | Two    |
+----+--------+
2 rows in set (0.00 sec)

mysql> REPLACE INTO B SELECT * FROM A;
Query OK, 4 rows affected (0.00 sec)
Records: 2  Duplicates: 2  Warnings: 0

mysql> SELECT * FROM B;
+----+--------+
| id | foo    |
+----+--------+
|  1 | One-Up |
|  2 | Two    |
+----+--------+
2 rows in set (0.00 sec)

mysql> DELETE FROM A where id = 1;
Query OK, 1 row affected (0.00 sec)

mysql> REPLACE INTO B SELECT * FROM A;
Query OK, 2 rows affected (0.00 sec)
Records: 1  Duplicates: 1  Warnings: 0

mysql> SELECT * FROM A;
+----+------+
| id | foo  |
+----+------+
|  2 | Two  |
+----+------+
1 row in set (0.00 sec)

mysql> SELECT * FROM B;
+----+--------+
| id | foo    |
+----+--------+
|  1 | One-Up |
|  2 | Two    |
+----+--------+
2 rows in set (0.00 sec)