0

Я пытаюсь нормализовать таблицу в MySQL, преобразовывая таблицу со многими подобными столбцами в отношения «многие ко многим» с двумя столбцами. У меня есть следующие таблицы:Заполнение многоцветной таблицы персонажей с использованием трех таблиц в MySQL

лицо:

+----+------+ 
| id | name | 
+----+------+ 
| 1 | John | 
| 2 | Anna | 
| 3 | Leon | 
+----+------+ 

person_temp:

+------+--------+--------+--------+--------+ 
| name | color1 | color2 | color3 | color4 | 
+------+--------+--------+--------+--------+ 
| John | red | blue | green |  | 
| Anna | green | yellow |  |  | 
| Leon | blue | red |  |  | 
+------+--------+--------+--------+--------+ 

цвет:

+----+--------+ 
| id | name | 
+----+--------+ 
| 1 | red | 
| 2 | blue | 
| 3 | green | 
| 4 | yellow | 
+----+--------+ 

Я хотел бы удалить person_temp после заполнения многие-ко-многим отношение таблица примерно такой:

человек цвет:

+-----------+----------+ 
| person_id | color_id | 
+-----------+----------+ 
|  1  | 1  | 
|  1  | 2  | 
|  1  | 3  | 
|  2  | 3  | 
|  2  | 4  | 
|  3  | 2  | 
|  3  | 1  | 
+-----------+----------+ 

Однако я не нашел решения на мой запрос. Единственное отношение, которое у меня есть к идентификатору человека, - это имя в person_temp. Я знаю, что имена уникальны лично, поэтому было бы нецелесообразно использовать их для запроса.

Я попытался с этим SQL, но он не работает, потому что person_temp не имеет столбца id.

INSERT INTO `person_color` 
SELECT p.id, c.id 
FROM (
    SELECT id, color1 color 
    FROM person_temp 
    UNION 
    SELECT id, color2 FROM person_temp 
    UNION 
    SELECT id, color3 FROM person_temp 
    UNION 
    SELECT id, color4 FROM person_temp 
    UNION 
    SELECT id, color5 FROM person_temp 
) p 
    JOIN color c 
    ON c.name = p.color; 
+1

Если у вас нет 'id' в' person_temp', вам нужно присоединиться к таблице 'person' с' именем' на обеих таблицах. – Viki888

+2

Вы не нормализуетесь, либо в смысле придумывания реляционного дизайна, либо в смысле более высоких нормальных форм. Вы просто улучшаете дизайн. PS Ваш код был очень близок, см. Мой ответ. – philipxy

ответ

0

благодаря @ Viki888 Я думаю, я решил запрос

1

Ваш исходный запрос прост и близок. Кроме того, выбирая name s не id s от person_temp, вам просто нужно ПРИСОЕДИНЯЙТЕСЬ с name s с их id s от person в конце. Вам не нужно делать все эти JOINs до person_temp отдельно.

INSERT INTO person_color 
SELECT p.id AS person_id, c.id AS color_id 
FROM (
    SELECT name, color1 AS color FROM person_temp 
    UNION 
    SELECT name, color2 FROM person_temp 
    UNION 
    SELECT name, color3 FROM person_temp 
    UNION 
    SELECT name, color4 FROM person_temp 
    UNION 
    SELECT name, color5 FROM person_temp 
) nc 
JOIN color c 
    ON c.name = nc.color 
JOIN person p 
    ON p.name = nc.name; 

Строки таблицы не имеют порядка, так что бессмысленно ORDER BY p.id, c.id в INSERT. Строки вывода имеют порядок.

PS Вы не нормализуетесь ни в смысле придумывания реляционной конструкции, ни в смысле более высоких нормальных форм. Вы просто улучшаете дизайн.

0

Для чего это стоит, я бы не потрудился сделать это таким умным способом, как раз для этого в одном запросе. Для этого нет никакой пользы.

Проще написать код, чтобы сделать это за несколько проходов, и упростить означает, что вы выполняете работу быстрее.

INSERT INTO `person-color` (person_id, color_id) 
SELECT p.id, c.id 
FROM person p 
JOIN person_temp pt ON p.name=pt.name 
JOIN color c ON pt.color1=c.name; 

INSERT INTO `person-color` (person_id, color_id) 
SELECT p.id, c.id 
FROM person p 
JOIN person_temp pt ON p.name=pt.name 
JOIN color c ON pt.color2=c.name; 

INSERT INTO `person-color` (person_id, color_id) 
SELECT p.id, c.id 
FROM person p 
JOIN person_temp pt ON p.name=pt.name 
JOIN color c ON pt.color3=c.name; 

INSERT INTO `person-color` (person_id, color_id) 
SELECT p.id, c.id 
FROM person p 
JOIN person_temp pt ON p.name=pt.name 
JOIN color c ON pt.color4=c.name; 

Нет необходимости использовать UNION или ORDER BY.