複数のMySQL行を1つのフィールドに連結できますか?


1214

を使用するとMySQL、次のようなことができます:

SELECT hobbies FROM peoples_hobbies WHERE person_id = 5;

私の出力:

shopping
fishing
coding

しかし、代わりに私は1行1列が欲しいだけです:

期待される出力:

shopping, fishing, coding

その理由は、複数のテーブルから複数の値を選択していて、すべての結合の後で、希望よりもはるかに多くの行があるためです。

MySQL Docで関数を探しましたが、CONCATまたはCONCAT_WS関数が結果セットを受け入れないようです。

それで、ここの誰かがこれを行う方法を知っていますか?


9
私はgroup_concatの使用方法について少しデモを書いたところです。これはあなたに役立つかもしれません:giombetti.com/2013/06/06/mysql-group_concat
Marc Giombetti

回答:


1739

使用できますGROUP_CONCAT

SELECT person_id, GROUP_CONCAT(hobbies SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;

ルートヴィヒがコメントで述べたようにDISTINCT重複を避けるために演算子を追加することができます:

SELECT person_id, GROUP_CONCAT(DISTINCT hobbies SEPARATOR ', ')
FROM peoples_hobbies 
GROUP BY person_id;

Jan がコメントで述べたように、次のコマンドを使用して、値を分解する前に値を並べ替えることもできますORDER BY

SELECT person_id, GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;

Dagがコメントで述べたように、結果には1024バイトの制限があります。これを解決するには、クエリの前にこのクエリを実行します。

SET group_concat_max_len = 2048;

もちろん、2048必要に応じて変更できます。値を計算して割り当てるには:

SET group_concat_max_len = CAST(
    (SELECT SUM(LENGTH(hobbies)) + COUNT(*) * LENGTH(', ')
    FROM peoples_hobbies 
    GROUP BY person_id)
    AS UNSIGNED
);

155
結果の列の1024バイトの制限に注意してください(パラメーターgroup_concat_max_lenを参照)
Dag

81
DISTINCTパラメータを追加すると、ダブルは取得されません。... GROUP_CONCAT(DISTINCT hobbies)
ルートヴィヒ

3
1つの列からすべてのデータを取得する必要がありました。これを行うためにGROUP BY句を使用しないでください。例:SELECT GROUP_CONCAT(emails SEPARATOR '、')FROM users;
Jonathan Bergeron

1
ありがとう、グループ連結の長さに制限があることを知りませんでした。私が生成したモンスターリストを回避するには、それが必要でした。
Patrick

9
あなたは結果の爆縮の文字列の使用に趣味をソートしたい場合:SELECT person_id, GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ') FROM peoples_hobbies GROUP BY person_id
ジャン

106

GROUP_CONCATMySQLバージョン(4.1)でサポートされているかどうかを確認してください。詳細については、ドキュメントを参照しください。

それは次のようになります:

  SELECT GROUP_CONCAT(hobbies SEPARATOR ', ') 
  FROM peoples_hobbies 
  WHERE person_id = 5 
  GROUP BY 'all';

11
group by 'all'すべての行に文字列allを割り当て、これらの行の間で文字列を比較するため、これは不要である(さらに望ましくない)と思います。私は正しいですか?
Krzysiek 2014年

74

複数の個別の行を連結する代替構文

警告:この投稿はお腹がすくなります。

与えられた:

グループではなく、複数の個別の行選択し、特定のフィールドを連結したいと思っていました。

製品IDとその名前および価格の表があるとします。

+------------+--------------------+-------+
| product_id | name               | price |
+------------+--------------------+-------+
|         13 | Double Double      |     5 |
|         14 | Neapolitan Shake   |     2 |
|         15 | Animal Style Fries |     3 |
|         16 | Root Beer          |     2 |
|         17 | Lame T-Shirt       |    15 |
+------------+--------------------+-------+

次に、これらの子犬をチェックボックスとして一覧表示する派手なajaxがあります。

空腹のカバのユーザーがを選択し13, 15, 16ます。今日は彼女にデザートはありません...

検索:

純粋なmysqlを使用して、ユーザーの注文を1行に要約する方法。

解決:

使用GROUP_CONCATしてIN

mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary FROM product WHERE product_id IN (13, 15, 16);

どの出力:

+------------------------------------------------+
| order_summary                                  |
+------------------------------------------------+
| Double Double + Animal Style Fries + Root Beer |
+------------------------------------------------+

ボーナスソリューション:

あなたも合計価格が必要な場合は、トスSUM()

mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary, SUM(price) AS total FROM product WHERE product_id IN (13, 15, 16);
+------------------------------------------------+-------+
| order_summary                                  | total |
+------------------------------------------------+-------+
| Double Double + Animal Style Fries + Root Beer |    10 |
+------------------------------------------------+-------+

PS:近くにIn-N-Outがない場合は謝罪...


11
これは良い答えですが、純粋に答えるというより広告のように聞こえます。それでも、適切にフォーマットされた適切な答えです。
FliiFe 2016年

1
サポートを利用できますか?stackoverflow.com/q/60278898/11697039 @elbowlobstercowstand
zus



25

私の場合、IDの行があり、それをcharにキャストする必要がありました。それ以外の場合、結果はバイナリ形式にエンコードされました。

SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table

1
ありがとう!せずにCASTI LIKE値は持っていた[BLOB - 14 Bytes]結果では!
Mel_T

1
私はヘルプを入手できますstackoverflow.com/q/60278898/11697039 @Fedir RYKHTIK
zus

16

次のようなMySQL(5.6.13)セッション変数と代入演算子を使用します

SELECT @logmsg := CONCAT_ws(',',@logmsg,items) FROM temp_SplitFields a;

その後、あなたは得ることができます

test1,test11

2
GROUP_CONCATよりも高速ですか?
jave.web

1
私は、テストテーブルの説明列(varchar(50))でMySQLサーバーv5.6.17を使用してPHPMyAdminでこれをテストしましたが、各レコードのBLOBフィールドを返します:SELECT @logmsg := CONCAT_ws(',',@logmsg,description) from test
Jan

14

私はより複雑なクエリを持っていて、GROUP_CONCATそれを機能させるために外部クエリで使用する必要があることがわかりました。

元のクエリ:

SELECT DISTINCT userID 
FROM event GROUP BY userID 
HAVING count(distinct(cohort))=2);

Imploded:

SELECT GROUP_CONCAT(sub.userID SEPARATOR ', ') 
FROM (SELECT DISTINCT userID FROM event 
GROUP BY userID HAVING count(distinct(cohort))=2) as sub;

これが誰かを助けることを願っています。


9

ここGROUP_CONCATでサブクエリの使用方法を探している人のために-この例を投稿する

SELECT i.*,
(SELECT GROUP_CONCAT(userid) FROM favourites f WHERE f.itemid = i.id) AS idlist
FROM items i
WHERE i.id = $someid

したがってGROUP_CONCAT、サブクエリ内では使用せず、ラップしないでください。


1
これがまさに私が探していたものでした
bumerang

7

これを試して:

DECLARE @Hobbies NVARCHAR(200) = ' '

SELECT @Hobbies = @Hobbies + hobbies + ',' FROM peoples_hobbies WHERE person_id = 5;

2
これは私が得たものです: '認識されないステートメントタイプ。(位置0の「DECLARE」の近く)」
イスティアケアーメド

1

MySqlで列を連結する2つの方法があります

select concat(hobbies) as `Hobbies` from people_hobbies where 1

または

select group_concat(hobbies) as `Hobbies` from people_hobbies where 1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.