用另一个表中的唯一值更新一个表?

时间:2013-07-17 15:51:49

标签: mysql

我们从项目的一个表开始,很快意识到我们需要多个表来完成我们想要做的事情。

我们开始切换,但现在我想完全从一个表切换到多个。

我现在拥有的内容:

TABLE: CONTACT
+-----+-------+--------+----------+
| id  | fname | lname  | phone    |
+-----+-------+--------+----------+
| 123 | John  | Doe    | 555-1234 |
| 124 | Mary  | Shelly | 555-5857 |
| 125 | Jane  | Doe    | NULL     |
+-----+-------+--------+----------+

TABLE: PHONE
+----+--------+----------+------+
| id | con_id |   phone  | main |
+----+--------+----------+------+
| 1  | 125    | 555-5857 | N    |
+----+--------+----------+------+

所以我们有一些被添加和更改的内容。现在,我需要从CONTACT表中添加PHONE表中尚未包含的所有数据。我用临时表来做到这一点:

TABLE: temp
+------------+----------+------+
| foreign_id |   phone  | main |
+------------+----------+------+
| 123        | 555-1234 | Y    |
| 124        | 555-4153 | Y    |
| 125        | 555-5857 | N    |
+------------+----------+------+

但是当我从temp添加到手机时,我最终会有重复的条目(在示例中,contact.id = 125)。

这就是我想要的目标:

TABLE: CONTACT
+-----+-------+--------+
| id  | fname | lname  |
+-----+-------+--------+
| 123 | John  | Doe    |
| 124 | Mary  | Shelly |
| 125 | Jane  | Doe    |
+-----+-------+--------+


TABLE: PHONE
+----+--------+----------+------+
| id | con_id |   phone  | main |
+----+--------+----------+------+
| 1  | 125    | 555-5857 | N    |
| 2  | 123    | 555-1234 | Y    |
| 3  | 124    | 555-4153 | Y    |
+----+--------+----------+------+

我运行的命令:

create temporary table temp (select t2.id, phone from contact t2);
alter table temp add main varchar(1);
update temp set main = "Y";

insert into phone (con_id, phone, main) select id, phone, main from temp;
drop table temp;

最终,我将从联系中删除“电话”列。问题是,如果表格中已经存在电话号码的条目,我就会留下重复的内容。 如何防止这种情况?

另外,如果我做错了,我也可以改变它。我只是觉得临时表可能是最好的方法吗?

1 个答案:

答案 0 :(得分:2)

您可以通过向电话表添加主键(或唯一键)来避免重复:

ALTER TABLE phone ADD PRIMARY KEY (con_id);

这将确保每个con_id只有一个条目。如果您想为每个con_id允许多个电话号码,则应使用:

ALTER TABLE phone ADD PRIMARY KEY (con_id, phone);

现在,您可以直接从联系人表格或临时表中插入条目,如果您已将联系人列中的电话列删除:

REPLACE INTO phone (con_id,phone,main) 
   SELECT id, phone, "Y" FROM contact;

或者,您可以使用INSERT ... ON DUPLICATE KEY UPDATE ...构造。 如果您不想覆盖但保留原始的非主键值,则可以使用INSERT IGNORE。

有关INSERT语法的更多详细信息,请参阅:http://docs.oracle.com/cd/E17952_01/refman-5.1-en/insert.html