2016-08-19 4 views
0

複数の列にデータを広げたテーブルを多対多のテーブルに正規化したいと考えています。私の場合は複数の列を1つの多数のテーブルからMySQLのテーブルに正規化する

、私はhobbyテーブルで検出された名前を含むhobby1hobby2hobby3hobby4文字列でpersonテーブルを持っています。いくつかは空ではありません。

現在、DB設計は次のようになります。

original database design

現在person_hobbyは空です。

あなたはので、私は後でそれらを取り除くことができhobby.nameに関連hobby列で見つかったすべての文字列をperson_hobbyテーブルを取り込むためのSQLクエリで私を助けることができますか?すべての趣味フィールドの

おかげ

+1

あなたの 'hobby'テーブルにはすでにデータが入っていますか?また、SOは "私のためのコードを書く"サイトではありませんので、あなた自身でこの問題を解決しようとしてください。 (1つのヒントは 'INSERT ... SELECT'です、ドキュメントを別名調べます... rtfm) – Jakumi

+0

うまくいかない場合、試行を投稿するポイントは何ですか?これは、同じ問題を抱えている他の人々を助ける真の質問です。私は他のstackoverflowユーザーへの私の質問を助けるために架空のデータを正確に使用しています。 – denoise

+0

私が理解する限り、あなた自身では解決できない問題に遭遇したときにSOが助けます。 AFAIKこれは 'INSERT ... SELECT'で非常に簡単ですので、私が懸念している限り、失敗した試行を表示するまで問題はありません。 – Jakumi

答えて

3

例えば:

DROP TABLE IF EXISTS person; 

CREATE TABLE person 
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
,name VARCHAR(12) NOT NULL 
,hobby1 VARCHAR(15) NULL 
,hobby2 VARCHAR(15) NULL 
,hobby3 VARCHAR(15) NULL 
,hobby4 VARCHAR(15) NULL 
); 

DROP TABLE IF EXISTS person_hobby; 

CREATE TABLE person_hobby 
(person_id INT NOT NULL 
,hobby_id INT NOT NULL 
,PRIMARY KEY(person_id,hobby_id) 
); 

DROP TABLE IF EXISTS hobby; 

CREATE TABLE hobby 
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
,name VARCHAR(15) NOT NULL UNIQUE 
); 

INSERT INTO person VALUES 
(1,'John' ,'Reading' ,'Cycling','Swimming',NULL), 
(2,'Paul' ,'Travelling','TV','Bird watching','Cinema'), 
(3,'George','Fishing' ,'Swimming',NULL,NULL), 
(4,'Ringo',NULL,NULL,NULL,NULL); 

INSERT INTO hobby (name) 
SELECT hobby1 FROM person WHERE hobby1 IS NOT NULL UNION 
SELECT hobby2 FROM person WHERE hobby2 IS NOT NULL UNION 
SELECT hobby3 FROM person WHERE hobby3 IS NOT NULL UNION 
SELECT hobby4 FROM person WHERE hobby4 IS NOT NULL; 

INSERT INTO person_hobby 
SELECT p.id 
    , h.id 
    FROM 
    (
SELECT id 
    , hobby1 hobby 
    FROM person 
UNION 
SELECT id 
    , hobby2 
    FROM person 
UNION 
SELECT id 
    , hobby3 
    FROM person 
UNION 
SELECT id 
    , hobby4 
    FROM person 
    ) p 
    JOIN hobby h 
    ON h.name = p.hobby; 

Query OK, 9 rows affected (0.05 sec) 
Records: 9 Duplicates: 0 Warnings: 0 

SELECT * FROM person_hobby; 
+-----------+----------+ 
| person_id | hobby_id | 
+-----------+----------+ 
|   1 |  1 | 
|   1 |  4 | 
|   1 |  6 | 
|   2 |  2 | 
|   2 |  5 | 
|   2 |  7 | 
|   2 |  8 | 
|   3 |  3 | 
|   3 |  6 | 
+-----------+----------+ 

は今、人のテーブルから列をドロップします。

0

繰り返し(ON -clauseでhobby1に気づく):

INSERT IGNORE INTO person_hobby (person_id, hobby_id) 
    SELECT person.id, hobby.id 
    FROM person 
    INNER JOIN hobby ON (person.hobby1=hobby.name) 
関連する問題