MySQL 1対他のデータをGROUP_CONCATで取得

MySQL

1対他のデータ構造を関連づけて表示する、というのはよくある動作ですが、GROUP BY とGROUP_CONCATを利用して、1対他のデータを取得してまとめる方法です。

文章で書いてもよくわからないと思うので、例をあげてみます。

ここに2つのテーブルがあります。
ninjyaテーブルと、skillテーブルです。
ninjyaテーブルには、忍者の名前、skillテーブルには必殺技の名前が格納されています。
一人の忍者は多くの必殺技を持つという、1対他のデータ構造になっています。

|>|ninjya テーブル|h
|id|name|h
|1|ナルト|
|2|サスケ|

#br

|>|>|skill テーブル|h
|id|ninjya_id|name|h
|1|1|螺旋丸|
|2|1|ナルトキック|
|3|2|千鳥|
|4|2|天照|

忍者の名前と、その必殺技のテーブルを表示したいとします。
ninjya_idで関連付けをし、GROUP_CONCATを次のように利用します。

 SELECT
 	ninjya.name, GROUP_CONCAT(skill.name)
 FROM
 	ninjya
 JOIN
 	skill on skill.ninjya_id = ninjya.id
 GROUP BY
 	ninjya.id

次のような結果が取得できます。
|name|GROUP_CONCAT( skill . name )|h
|ナルト|螺旋丸,ナルトキック|
|サスケ|千鳥,天照|

この例だと GROUP BYがいらないかのようですが、GROUP_CONCATを利用するために、グルーピングが必要です。

ちなみに、GROUP_CONCATがないと、ただ単にninjya.idから1件のデータを取得するだけです。

 SELECT
 	ninjya.name, skill.name
 FROM
 	ninjya
 JOIN
 	skill on skill.ninjya_id = ninjya.id
 GROUP BY
 	ninjya.id

上記のSQLの結果は次の通りです。
|name|name|h
|ナルト|螺旋丸|
|サスケ|千鳥|

ちなみに、一番最初のSQL文の出力結果が、フィールド名がGROUP_CONCATが入っていて見苦しいので、仕上げにエイリアスをつけておきます。

 SELECT
 	ninjya.name, GROUP_CONCAT(skill.name) as skill_name
 FROM
 	ninjya
 JOIN
 	skill on skill.ninjya_id = ninjya.id
 GROUP BY
 	ninjya.id

出力結果は次の通りです。
|name|skill_names|h
|ナルト|螺旋丸,ナルトキック|
|サスケ|千鳥,天照|

GROUP_CONCATのデフォルトはカンマ区切りですが、セパレーターは変更することができます。
http://dev.mysql.com/doc/refman/5.1/ja/group-by-functions.html

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です