2010-10-08 11 views
6

Tengo una tabla existente que se parece a esto. El número de barras a foo es exactamente dos en realidadEn MySQL, ¿cómo puedo dividir una tabla existente en muchas tablas nuevas relacionadas?

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

Y como esto me hace llorar, quiero dividirlo en dos tablas como esta

table foo_new 
ID   int 
name   string 
ID_bar_1  int 
ID_bar_2  int 

table bar_new 
ID   int 
name   string 
code   int 

Mi pregunta es, ¿cómo puedo escribir una secuencia de comandos que creará un registro coincidente en foo_new para cada existente en foo_old, incluidos nuevos ID para los nuevos registros bar_new asociados?

+0

puede "código" identificar una "barra" por su "foo"? – MatTheCat

+0

Debería haber elegido un nombre más claro como 'país', porque en mi situación no hay una clave única "en realidad" para el bar – Matt

Respuesta

6

En primer lugar crear las tablas foo_new y bar_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) 
); 

A continuación, llenar la tabla bar_new con todos los bares distinto del foo_old:

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; 

luego unirse foo_old con bar_new rellenar 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); 
caso

prueba:

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); 

Así es como foo_new y bar_new se verá como después de la operación anterior:

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) 
+0

¡Impresionante! Tuve que hacer algunos pequeños cambios ya que, mal por no ser claro, el código no es una clave. Por suerte puedo añadir una, así que mi solución final se parece a esto INSERT INTO bar_new (nombre, código, id_foo) nombre bar_name_1 SELECT, bar_code_1, el código de identificación de foo_old UNION ALL SELECT nombre bar_name_2, bar_code_2, el código de identificación de foo_old INSERT INTO 'foo_new' (nombre, id_bar_1, id_bar_2) f.name SELECT, b1.id, b2.id DE foo_old f JOIN bar_new b1 ON (b1.id_foo = f.id) y (b1 .name = f.bar_name_1) JOIN bar_new b2 ON (b2.id_foo = f.id) AND (b2.name = f.bar_name_2) – Matt

+0

En serio, las personas deben dejar de usar foo bar y simplemente inventar ejemplos razonables. realmente dificulta la capacidad de comprender el problema. – AndrewMcLagan

Cuestiones relacionadas