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

暇なときに予定を探せるアプリ[yoteiPicker](https://yoteipicker.com/)をリリースしました。

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

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

[＞＞フリーランスも対象！エンジニア転職におすすめなサイト5選](https://www.kamome-susume.com/enginner-job-change-site/
)

## ゴール
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](https://yoteipicker.com/)をリリースしました。

[＞＞フリーランスも対象！エンジニア転職におすすめなサイト5選](https://www.kamome-susume.com/enginner-job-change-site/
)