LoginSignup
2
2

More than 1 year has passed since last update.

【Laravelクエリビルダ】複数のカラムをgroupByでグループ化させる

Last updated at Posted at 2021-07-14

暇なときに予定を探せるアプリyoteiPickerをリリースしました。

Laravelのクエリビルダで複数のカラムをグループ化させる方法を解説します。

バージョンは6系です。
ブログで以下の記事も書いているので、ぜひチェックしてください!

>>フリーランスも対象!エンジニア転職におすすめなサイト5選

ゴール

user_idとpost_nameでグループ化させる

post_id user_id post_name
1 1 カレー
2 2 ちゃんこ
3 3 チャーハン
4 1 オムライス
5 2 ちゃんこ

user_id post_name
1 オムライス
1 カレー
2 ちゃんこ
3 チャーハン

複数のカラムをグループ化させる時の注意点

よくありがちなのが、

user_id post_name
1 オムライス,カレー
2 ちゃんこ
3 チャーハン

のようにできると考えてしまうことです。

post_nameにオムライス、カレーのように複数の項目を入れることはできません。

user_idとpost_nameでグループ化させているので、
①user_id→1,1,2,2,3でグループ化
=>1,2,3
②post_name→オムライス、カレー、ちゃんこ、ちゃんこ、チャーハンでグループ化
=>オムライス、カレー、ちゃんこ、チャーハン

ただ、オムライスはuser_id→1、カレーはuser_id→1なので、別々の項目としてデータを取得します。

よって①と②により、

user_id post_name
1 オムライス
1 カレー
2 ちゃんこ
3 チャーハン

となるわけです。

サンプルコード

モデルにデータ取得のロジック、コントローラーに変数格納してビューに変数をわたし、ビューでforeachを用いてデータを表示させていきましょう。

モデル(Post.php)

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;←忘れずに追加するこれでDB::使用可能

class Post extends Model
{
    public function getResult()
    {
      // user_id,post_nameでグループ化
      return DB::table('posts')
              ->select('user_id', 'post_name')
              ->groupBy('user_id', 'post_name')
              ->get();
    }
}

コントローラー(PostController.php)

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Post;←バージョン8系なら use App\Models\Post;

class PostController extends Controller
{
    public function index()
    {
        $this->posts = new Post();

        $results = $this->posts->getResult();

        return view('posts.index', compact(
            'results',
        ));
    }
}

ビュー(index.blade.php)

<table>
    <thead>
      <tr>
        <th>ユーザーID</th>
        <th>ネーム</th>
      </tr>
    </thead>
    <tbody>
    @foreach ($results as $result)
      <tr>
        <td>{{ $result->user_id }}</td>
        <td>{{ $result->post_name }}</td>
      </tr>
    @endforeach
    </tbody>
</table>

エラーになるやつ

        return DB::table('posts')
              ->select('user_id', 'post_name')
              ->groupBy('user_id')
              ->get();

冒頭に解説した、user_idでまとめようとすると、post_nameが一部の項目で複数になってしまうのでエラー起きます。

SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'tests.posts.post_name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by (SQL: select `user_id`, `post_name` from `posts` group by `user_id`)

こんなエラー起きると思います。

簡単に言えば、“GROUP BY” で指定していないカラムが “SELECT” に入っているです。

group byでハマると抜け出すの大変なので、最初のうちは慣れるまで今季強う戦う必要がありますね。

今回はここまでです。他にもクエリビルダについて解説しています。

参考になりましたら、LGTMまたは記事のストックをお願いいたします。

ブログで以下の記事も書いているので、ぜひチェックしてください!

暇なときに予定を探せるアプリyoteiPickerをリリースしました。

>>フリーランスも対象!エンジニア転職におすすめなサイト5選

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2