💨

MySQLでGROUP_CONCATを使って、任意のカラムを結合した文字列の取得

2023/03/10に公開

書くこと

  • MySQLのGROUP_CONCATを利用して、任意の値を結合した文字列を取得する
  • group_concat_max_lenの落とし穴

想定

以下のモデルがあった時、

class Article(models.Model):
    id = models.BigAutoField(primary_key=True)
    # (省略)


class Comment(models.Model):
    id = models.BigAutoField(primary_key=True)
    # Article 1-* Comment
    article = models.ForeignKey(
        "Article",
        models.PROTECT,
        related_name="comments",
    )
    # (省略)

article_id毎のcomment.idの一覧をSQLで取得したい

article_id comment_ids
1 1,2
2 3,4,5

方法論

以下のクエリを実行

select article_id, GROUP_CONCAT(id) as comment_ids
from comments
group by article_id

落とし穴

注意事項

  • 最大文字列長がgroup_concat_max_lenの値に依存している
    • defaultsは1,024bytes
  • クエリ実行そのものは正常終了する

対策

システム変数を変更する

set Session group_concat_max_len = 10000;

付録: セパレーター(,)を任意の文字にする

select article_id, GROUP_CONCAT(id separator '-') as comment_ids
from comments
group by article_id
article_id comment_ids
1 1-2
2 3-4-5

Discussion