環境
mysql 8.0
やりたかったこと
mysql8のsqlにおいて、GROUP BY
して集約されたデータをjson形式にして、さらにdistinctをかけたかった。jsonで集約するのはJSON_ARRAYAGG関数を使うことができる。
例えば以下を実行すると
select u.sex, JSON_ARRAYAGG(u.name) from user u group by u.sex
userテーブルの中身を適当に脳内で補完してもらうと結果はこんな感じになる。
u.sex | u.name |
---|---|
男 | 鈴木,佐藤,山崎,鈴木,鈴木,佐藤,高橋 |
女 | 鈴木,滝,山中,山中 |
で、このままだとnameが重複してるのでdistinctした結果がほしいと思って
select u.sex, JSON_ARRAYAGG(distinct u.name) from user u group by u.sex
としてみたのだが、distinctが効かない。。
解決法
group_concat
であればdistinctは効くので、それとconcatを組み合わせて無理矢理jsonにするのがよいっぽい。
select u.sex, concat('[', group_concat(distinct u.name),']') as name from user u group by u.sex
自分が実際業務で使ったのはこれにJSON_OBJECTを絡めた、以下のようにjsonをまるっととってくる方式を採用した。
select
u.sex ,
concat('[', group_concat(distinct JSON_OBJECT('id', u.id, 'name', u.name)), ']') as name
from
user u
group by
u.sex
感想
JSON_ARRAYAGGでdistinct効かないのはmysqlの仕様なのか?バージョンアップでいつか直るといいなぁ。