21043


**前提**  
mainテーブル  
・idカラムの値が9のレコード1件(常に1件)

tableaテーブル  
・m_idカラムの値が9のレコード5件(idカラムの値によって変動)

tablebテーブル  
・m_idカラムの値が9のレコード1件(idカラムの値によって変動)

* * *

**この時、｢mainテーブル.idカラム」と「tableaテーブルm_idカラム」と「tablebテーブルm_idカラム」を結合してデータ取得したい**  
取得したい内容(idカラムの値は9)  
・mainテーブル全カラム  
・tableaテーブルcolaカラム5件分を連結した内容  
・tablebテーブルcolbカラム1件分(を連結した内容)

* * *

**うまくいかないSQL**  
・colbconcatの連結数がcolaconcatと同じになってしまう

[code]

    SELECT 
      m.*,
      GROUP_CONCAT(a.cola) AS colaconcat,
      GROUP_CONCAT(b.colb) AS colbconcat,
    FROM main AS m
      LEFT JOIN tablea AS a ON (m.id = a.m_id)
      LEFT JOIN tableb AS b ON (m.id = b.m_id)
    WHERE m.id = 9
    GROUP BY m.id
    
[/code]

下記のような内容を期待しているけど  
★,☆,■,□,●  
▲

実際に取得される内容は  
★,☆,■,□,●  
▲,▲,▲,▲,▲


CC BY-SA 3.0
2016-01-18T14:02:18.113
21041
2016-01-18T15:27:58.950
2016-01-18T15:16:00.757
8000
7886
question
mysql sql
「GROUP_CONCAT」を2カラムに対して指定すると、思うような取得結果が取れない。結合の仕方がおかしい？


[`group_concat()`](http://dev.mysql.com/doc/refman/5.6/ja/group-by-
functions.html#function_group-concat)
関数は各行の値を連結するわけですが、質問に書かれたSQLの場合、連結前はどのような表になっているでしょうか。

[code]

    SELECT 
      id, cola, colb
    FROM main AS m
      LEFT JOIN tablea AS a ON (m.id = a.m_id)
      LEFT JOIN tableb AS b ON (m.id = b.m_id)
    WHERE m.id = 9
    
[/code]

mainの行に対してtableaとtablebを同時にJOINしているので・・・

[code]

    9,1,1
    9,2,1
    9,3,1
    9,4,1
    9,5,1
    
[/code]

`group_concat(colb)` とすると、`1,1,1,1,1` になるわけです。

期待通りの結果を得るには、JOINする前に `group_concat()` する必要があります。

[code]

    SELECT 
      m.*, a.colaconcat, b.colbconcat
    FROM main AS m
      LEFT JOIN (
        SELECT m_id, group_concat(cola) AS colaconcat FROM tablea
      ) AS a ON (m.id = a.m_id)
      LEFT JOIN (
        SELECT m_id, group_concat(colb) AS colbconcat FROM tableb
      ) AS b ON (m.id = b.m_id)
    WHERE m.id = 9;
    
[/code]

こうなるとサブクエリの方がわかりやすいかもしれません（パフォーマンスは知りませんが）。

[code]

    SELECT 
      m.*,
      (SELECT group_concat(cola) FROM tablea WHERE m_id = m.id) AS colaconcat,
      (SELECT group_concat(colb) FROM tableb WHERE m_id = m.id) AS colbconcat
    FROM main AS m
    WHERE m.id = 9;
    
[/code]

JOINでは各テーブルの対応する行全ての組み合わせが結果に表れます。今回はtableb側が1行だったのでたまたまtableaの行数と一致しましたが、tablebが複数行だったらもっと増えていたことでしょう。


CC BY-SA 3.0
2016-01-18T15:16:35.047
21043
2016-01-18T15:27:58.950
2016-01-18T15:27:58.950
8000
8000
21041
answer