実現したいこと
MySQL 5.7 で、JSON で SELECT
したいです。
前提
現状はJSON_ARRAYAGG(JSON_OBJECT())
を使い JSON での SELECT
を実現していますが、下記 発生している問題 に記載したように、値がないときにまで取得されてしまいます。(問題というか正常な動作なのでしょうけれど。)
取得後に削除すれば済む話ですが、値があるときだけ取得するよう修正できないかと模索しています。
発生している問題
下記 該当のソースコード の SELECT
を実行すると、T.id
がないときにまで tags
の連想配列を(全てが null
の値で)生成してしまいます。
こうなるのです。
php
1[ 2 'id' => 1, 3 'tags' => [ 4 ['id' => null, 'name' => null] 5 ] 6]
該当のソースコード
こちらが問題の SELECT
です。
JSON_ARRAYAGG(JSON_OBJECT())
を使い JSON で SELECT
しています。
MySQL
1SELECT 2 C.id, 3 4 -- tags 5 JSON_ARRAYAGG(JSON_OBJECT( 6 'id', T.id, 7 'name', T.name 8 )) AS tags 9 10FROM 11 t_comments C 12 LEFT JOIN t_comment_tags CT ON CT.comment_id = C.id 13 LEFT JOIN t_tags T ON T.id = CT.tag_id 14 15WHERE 16 C.supplier_id = 1 17 AND C.item_kind_id = 10 18 19GROUP BY C.id
試したこと
そこでT.id
の有無を確認してからJSON_ARRAYAGG(JSON_OBJECT())
を使うようCASE~WHEN
してみました。こちらです。
SELECT C.id, -- tags CASE WHEN T.id IS NOT NULL THEN JSON_ARRAYAGG(JSON_OBJECT( 'id', T.id, 'name', T.name )) ELSE NULL END AS tags FROM t_comments C LEFT JOIN t_comment_tags CT ON CT.comment_id = C.id LEFT JOIN t_tags T ON T.id = CT.tag_id WHERE C.supplier_id = 1 AND C.item_kind_id = 10 GROUP BY C.id
しかしこちらのエラーになります。
#1055 - Expression #11 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test_database.T.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
もちろん、「only_full_group_by
の解除」という解決策は採りたくありません。
あと自力で考えられる解決策はGROUP BY C.id
をGROUP BY C.id, T.id, T.name
と記述することですが、汚いですよね。(実際にはC.id
以外にもC.title
やC.author_id
など多数のカラムがありそれら全て記述しないといけません。)
補足情報(FW/ツールのバージョンなど)
MySQL 5.7 です。
PHP の PDO で実行します。
もしこういったケースに対する良い解決策がございましたらご指導を賜りますようお願い申し上げます。

回答1件
あなたの回答
tips
プレビュー