[MySQL][CakePHP4] GROUP_CONCAT でカラム値を連結したい&group_concat_max_len システム変数
の続きです。
結論
- 2020年11月29日時点で CakePHP4 には GROUP_CONCAT 関数は実装されていない
- マジックメソッドによりMySQL の関数を直接実行するので
group_concat
と書けば動く - postgreSQL, SQL Server, SQLite に対し、機能追加の PR が出ているがまだマージされていない
- よって、MySQL 以外はまだ使えない
- マージされたら RDBMS の種類関係なくキャメルケースの
groupConcat
として使える
GROUP_CONCAT の PR
@ktouさんが調べてくださった CakePHP4 の GROUP_CONCAT の PR を読んでいて、なるほど MySQL はおそらくそのまま関数を実行していて、他のRDBMS では実行できないから PR 出されているんだな、と理解はしてたのですが、実際のコードと動きから実証したわけではありませんでした。
が、なんと引き続き調べてくださっていました。圧倒的感謝…
よって流れをまとめさせていただきます。
さすがです!group_concatがCakePHPの公式ドキュメントには載っていないということなので公式ドキュメントにも追加するのが私のオススメです!ところで、 https://t.co/ScMFIoKfHX がまだ作業中なので使えなそうな気がするんですが、なんで使えるんでしょうね。。。
— す (@ktou) November 12, 2020
僕も疑問だったんですが、軽く CakePHP4 本体のコードを追っていたら、CakePHP4 自体に存在しない関数はそのまま MySQL の関数を呼んでそう…と予測するところで考えるのをやめてしまってました。
そうしたら、なんと引き続きコードを追ってくださっていて…なんかもう僕がコードを追わせてしまった感じになっていて申し訳ない限りなのですが、これはもう感謝しかないということで Qiita に投稿している次第です。TL に埋もれさせてはいかん。
なるほど!私も確認してみました!FunctionsBuilderは未知のAPIでも関数を呼べるようになっていました! https://t.co/WuL6UBN7qH なので、->group_concat()とMySQLで呼ばれるような関数の書き方をしたら動いていたのでした!
— す (@ktou) November 20, 2020
該当のコードを引用します。
/**
* Magic method dispatcher to create custom SQL function calls
*
* @param string $name the SQL function name to construct
* @param array $args list with up to 3 arguments, first one being an array with
* parameters for the SQL function, the second one a list of types to bind to those
* params, and the third one the return type of the function
* @return \Cake\Database\Expression\FunctionExpression
*/
public function __call(string $name, array $args): FunctionExpression
{
return new FunctionExpression($name, ...$args);
}
なるほど…CakePHP4 にない関数が呼ばれた場合はマジックメソッドで処理されるんですね。そしてたまたま group_concat とスネークケースで書いていたので、MySQL と同じ関数だったので実行できていた、ということでした。
また、PR がマージされたら、 groupConcat
とキャメルケースで呼び出すのが正しい実装となると思います。
で、Qiitaにまとめてくれた情報ですが、この情報はMySQL固有の話なので->group_concat()でOKです!関連情報として https://t.co/ScMFIoKfHX でMySQL以外でも同じAPIでGROUP_CONCAT()相当を使えるようなるのでマージされたら->groupConcat()の方が適切、という感じです!
— す (@ktou) November 20, 2020
今後
上記の PR がマージされたら、改めて動作検証した結果を反映します。
感謝
Twitterで軽い気持ちでわからないことを呟いたら、あれよあれよと言う間にすごい人たちがリプをくださり、検証してくださって、本当に感謝しかないです。
僕にとって、Twitterって世界はほんといつもいい刺激とインプットがもらえる最高の場所だし、最高な人がたくさんいて最高だなって語彙を失うレベルで日々みています。
僕も最高だなって思ってもらえるよう今後も活動していかねばって思わせていただいてます。
本当にいつも感謝です!ありがとうございますm(__)m