在MySQL中,我如何将一个现有的表拆分成许多新的相关表?

8

我有一个类似于这样的现有表格。实际上,foo所需的条形数确切为两个。

table foo_old
 ID           int
 name         string
 bar_name_1   string
 bar_code_1   int
 bar_name_2   string
 bar_code_2   int

鉴于这让我感到难过,我想将其拆分为两个表格,如下所示

table foo_new
 ID           int
 name         string
 ID_bar_1     int
 ID_bar_2     int

table bar_new
 ID           int
 name         string
 code         int

我的问题是,我该如何编写一个脚本来为 foo_old 中的每个现有记录创建一个匹配的记录到 foo_new 中,包括为新关联的 bar_new 记录创建新 ID?

代码能否为其foo识别bar? - MatTheCat
我应该选择一个更清晰的名称,比如“country”,因为在我的情况下,对于bar来说,并没有“实际上”的唯一键。 - Matt
1个回答

9

首先创建 foo_newbar_new 表:

CREATE TABLE foo_new (
   id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
   name varchar(100),
   id_bar_1 int,
   id_bar_2 int
);

CREATE TABLE bar_new (
   id int NOT NULL AUTO_INCREMENT PRIMARY KEY, 
   name varchar(100), 
   code int,
   UNIQUE (code)
);

接下来,将foo_old表中所有不同的酒吧填充到bar_new表中:

INSERT INTO bar_new (name, code) 
SELECT DISTINCT bar_name_1 name, bar_code_1 code FROM foo_old
UNION  
SELECT DISTINCT bar_name_2 name, bar_code_2 code FROM foo_old;

然后将foo_oldbar_new连接起来,填充foo_new

INSERT INTO `foo_new` (name, id_bar_1, id_bar_2)
SELECT  f.name, b1.id, b2.id
FROM    foo_old f
JOIN    bar_new b1 ON (b1.code = f.bar_code_1)
JOIN    bar_new b2 ON (b2.code = f.bar_code_2);

测试案例:

CREATE TABLE foo_old (
   id int NOT NULL PRIMARY KEY,
   name varchar(100),
   bar_name_1 varchar(100),
   bar_code_1 int,
   bar_name_2 varchar(100),
   bar_code_2 int   
);

INSERT INTO foo_old VALUES (1, 'foo1', 'bar1', 1, 'bar2', 2);
INSERT INTO foo_old VALUES (2, 'foo2', 'bar6', 6, 'bar5', 5);
INSERT INTO foo_old VALUES (3, 'foo3', 'bar4', 4, 'bar3', 3);
INSERT INTO foo_old VALUES (4, 'foo4', 'bar2', 2, 'bar7', 7);
INSERT INTO foo_old VALUES (5, 'foo5', 'bar6', 6, 'bar5', 5);
INSERT INTO foo_old VALUES (6, 'foo6', 'bar4', 4, 'bar1', 1);
INSERT INTO foo_old VALUES (7, 'foo7', 'bar7', 7, 'bar4', 4);
INSERT INTO foo_old VALUES (8, 'foo8', 'bar3', 3, 'bar8', 8);

这是在上述操作后foo_newbar_new的样子:
SELECT * FROM foo_new ORDER BY name;
+----+------+----------+----------+
| id | name | id_bar_1 | id_bar_2 |
+----+------+----------+----------+
|  3 | foo1 |        1 |        4 |
|  6 | foo2 |        2 |        7 |
|  5 | foo3 |        3 |        6 |
|  4 | foo4 |        4 |        5 |
|  7 | foo5 |        2 |        7 |
|  1 | foo6 |        3 |        1 |
|  2 | foo7 |        5 |        3 |
|  8 | foo8 |        6 |        8 |
+----+------+----------+----------+
8 rows in set (0.00 sec)


SELECT * FROM bar_new ORDER BY name;
+----+--------+------+
| id | name   | code |
+----+--------+------+
|  1 | bar1   |    1 |
|  4 | bar2   |    2 |
|  6 | bar3   |    3 |
|  3 | bar4   |    4 |
|  7 | bar5   |    5 |
|  2 | bar6   |    6 |
|  5 | bar7   |    7 |
|  8 | bar8   |    8 |
+----+--------+------+
8 rows in set (0.00 sec)

太棒了!我必须进行一些微小的更改,因为我的错误没有表明代码不是一个关键点。幸运的是,我可以添加一个,所以我的最终解决方案看起来像这样: <步骤1> INSERT INTO bar_new (name, code, id_foo) SELECT bar_name_1 name, bar_code_1, id code FROM foo_old UNION ALL
SELECT bar_name_2 name, bar_code_2, id code FROM foo_old<步骤2> INSERT INTO foo_new (name, id_bar_1, id_bar_2) SELECT f.name, b1.id, b2.id FROM foo_old f JOIN bar_new b1 ON (b1.id_foo = f.id) AND (b1.name = f.bar_name_1) JOIN bar_new b2 ON (b2.id_foo = f.id) AND (b2.name = f.bar_name_2)
- Matt
5
人们需要停止使用“foo”和“bar”,而是用一些合理的例子来说明问题,这样会更有助于理解问题。请勿直接翻译回去或提供其他信息。 - AndrewMcLagan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接