こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

GROUP_CONCAT✕複数列で、違うレコード数

MySQLで、「GROUP_CONCAT」を「複数列」に適用させ、それぞれ異なるレコードを1つにまとめようとしたのですが、
取得出来る結果が、多い方の数に引き連られてしまいます。

ざっくりとした質問でアレなのですが、これは結合の仕方が悪い、
と推測されるでしょうか?

そもそも「GROUP_CONCAT」を複数列に適用させる場合、それぞれ異なるレコード数をまとまることはできるのでしょうか?。


■期待した取得結果
[テーブルAカラムc] => tokyo,osaka
[テーブルAカラムd] => japan,japan

[テーブルBカラムe] => windows
[テーブルBカラムf] => man


■実際の取得結果
[テーブルAカラムc] => tokyo,osaka
[テーブルAカラムd] => japan,japan

[テーブルBカラムe] => windows,windows
[テーブルBカラムf] => man,man

「テーブルB」の取得結果が、「テーブルA」取得結果数に引き連られてしまいます


■SQL(抜粋)
SELECT
 GROUP_CONCAT(a.c) AS c,
 GROUP_CONCAT(a.d) AS d,
 GROUP_CONCAT(b.e) AS e,
 GROUP_CONCAT(b.f) AS f
FROM hoge h
LEFT JOIN テーブルA a ON (h.id = a.hoge_id)
LEFT JOIN テーブルB b ON (h.id = b.hoge_id)

投稿日時 - 2013-07-26 08:37:53

QNo.8192330

暇なときに回答ください

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

なんか説明がデータベーステーブルの行と列の考え方が90°狂っているとしか思えないんだが。id と他カラムとの関係が見えない。
group by がないんだけど、 tableごとに全行 group_concat したいだけですか?もしそうならjoin の順番を間違えてますね。

a テーブルからは、h テーブルにも同じid値が存在する行を選択して 全行に group_concat
b テーブルも同様
で各一行づつになったサブクエリをjoin であれば、以下
select * from
( select group_concat(c) as c, group_concat(d) as d from a where exists ( select * from h where a.id=h.id ) ) as a1
closs join
( select group_concat(e) as e, group_concat(f) as f from b where exists ( select * from h where b.id=h.id ) ) as b1 ;

投稿日時 - 2013-07-29 16:56:59

お礼

回答ありがとうございました。
再度考えてみますー

投稿日時 - 2013-08-01 21:27:54

ANo.1

「MySQL では、式のコンビネーションの連結された値を得ることができます。DISTINCT を使用することで、重複した値を除くことが可能です。結果の値をソートしたい場合は、ORDER BY 句を使用してください。」
と以下にあります。
http://dev.mysql.com/doc/refman/5.1/ja/group-by-functions.html

GROUP_CONCAT(distinct b.e) AS e,
・・・
にしてみるとうまくいきませんか?

なお、そもそもの考え方として、
>MySQLで、「GROUP_CONCAT」を「複数列」に適用させ、それぞれ異なるレコードを1つにまとめようとしたのですが、
とかかれておりますが、
>FROM hoge h
>LEFT JOIN テーブルA a ON (h.id = a.hoge_id)
>LEFT JOIN テーブルB b ON (h.id = b.hoge_id)
こう書いている時点で、

tokyo,japan,windows,man
osaka,japan,windows,man
の2レコードがあるテーブルに対する処理になりますので、
「異なるレコード」という表現はおかしいです。
「異なる集計条件(同一値は1つしか表示しない)」なら問題ないと思いますが。

なお、すべての項目にdistinctを書くと
>■期待した取得結果
とはならずに、以下となります。
[テーブルAカラムc] => tokyo,osaka
[テーブルAカラムd] => japan

[テーブルBカラムe] => windows
[テーブルBカラムf] => man

ちなみにどういうことをしたいのかがいまいち見えていないのですが。
例えば、
[テーブルAカラムc] => tokyo,osaka,New York,New York,London
[テーブルAカラムd] => japan,japan,USA,USA,GB
[テーブルBカラムe] => windows,windows,unix,linux,windows
[テーブルBカラムf] => man,man,woman,woman,man
(distinctなしのイメージ=質問文のSQL
 :順番指定なしのためこういう順序ででるかどうかはわかりませんが、
  まあ各項目が対応している形でたまたまでてくれたということで。)
というときにはどう出したいのでしょう?

[テーブルAカラムc] => tokyo,osaka,New York,London
[テーブルAカラムd] => japan,USA,GB
[テーブルBカラムe] => windows,unix,linux
[テーブルBカラムf] => man,woman
ですか(distinct付きのイメージ)
LondonはlinuxでWomanに見えてしまいそうですが。
(正しくはwindowsでManです。)

投稿日時 - 2013-07-28 13:29:30

補足

回答ありがとうございます。
やりたいのは以下のような感じです。

■前提
[テーブルAカラムc] => 「tokyo」「osaka」「New York」「New York」「London」
[テーブルAカラムd] => 「japan」「japan」「USA」「USA」「GB」
[テーブルBカラムe] => 「windows」「windows」「unix」「linux」「windows」
[テーブルBカラムf] => 「man」「man」「woman」「woman」「man」

この時、テーブルHがあって、
■テーブルHのidカラムとテーブルAのidカラムが一致したら、「GROUP_CONCAT」で「,」結合取得
[テーブルAカラムc] => tokyo,osaka,New York,New York,London
[テーブルAカラムd] => japan,japan,USA,USA,GB
※5つ一致した場合、5つを,で連結して取得

■テーブルHのidカラムとテーブルBのidカラムが一致したら、「GROUP_CONCAT」で「,」結合取得
[テーブルBカラムe] => windows,windows,unix,linux
[テーブルBカラムf] => man,man,woman,woman
※4つ一致した場合、4つを,で連結して取得


だけど、実際に取得してみたら、両方とも5つで取得されてしまう
なんででしょうか? という内容です。

distinctで重複削除したいわけではなくて、別カラムと一致した場合、それぞれの結合条件を満たすレコードを、すべて「,」で連結して抜き出したいけど、その結合条件を、2つのテーブルに対して行うと、おかしな感じになってしまいます。GROUP_CONCATというより、結合の仕方に問題がある(と推測される)のでしょうか?

投稿日時 - 2013-07-28 21:12:37

あなたにオススメの質問