syntax error or access violation: 1055
DBからGROUP BYを使って、データを取得する時に、以下のようなエラーが発生しました。
解決に3.4時間もかかってしまったため、解決方法を記しておきます。
syntax error or access violation: 1055 expression #2 of select list is not in group by clause and contains nonaggregated column...
環境
今回の環境は以下の通りです。
- PHP8.1
- Laravel8
ケーススタディ
あなたは、メッセージ機能を開発しています。
メッセージ一覧画面にて、最新のメッセージを取得して、日付とともに表示します。
テーブル例
サンプルのテーブルを用意しました。
id | sender | message | sent_at |
---|---|---|---|
1 | TOM | おはよう | 2022-06-01 |
2 | TOM | こんにちは | 2022-06-03 |
3 | HIRO | 今日暇? | 2022-06-04 |
4 | KAORU | 遊ぼうよ | 2022-06-04 |
5 | KEN | ねぇねぇ | 2022-06-05 |
6 | HIRO | 電話しても良い? | 2022-06-07 |
結論
結論から言うと、
GROUP BY で指定したカラムは、SELECTに入れる必要があります。
例えば、
$messages = Message::select('id','sender','message','sent_at')
->groupby('sender')
->get();
この場合、エラーが起きます。
syntax error or access violation: 1055 expression #2 of select list is not in group by clause and contains nonaggregated column...
GROUP BYの指定カラムを、SELECTにも入れる。
$messages = Message::select('id','sender','message','sent_at')
->groupby('id','sender','message','sent_at')
->get();
正しくは、GROUP BYの指定カラムを、SELECTにも入れてあげましょう。
GROUP BY と MAX を活用する
上記のように、GROUP BY と SELECT の数を整理すれば、エラーは解消されますが、本来の目的は達成できません。
GROUP BYは、MAXを併用すると、指定カラムを減らすことができます。
$messages = Message::select('id',DB::raw('MAX(sender)'),DB::raw('MAX(message)'),DB::raw('MAX(sent_at)'),)
->groupby(
'id'
)
->get();
まとめ
GROUP BYを使って、エラーが発生し、長時間はまってしまいました、、、。
この記事で、救われる人が増えることを信じてます。