副業におすすめなサイトを見る→

Laravelでカウント・合計値・平均値などを実装する方法

アプリリリースのお知らせ

予定を探すアプリyoteipickerをリリースしました。

アプリの利用用途:暇だから何か予定入れたいけど今週の土日は何しようかな〜?ってときに使えるアプリです。

Laravelでレコードのカウントや合計値、平均値を計算したい場合はどうすればいいんだろう…

こんな疑問を解決します。

結論、COUNT、SUM、AVG関数を使いましょう。

今回使用するテーブルはbooksテーブルで、以下のようなデータが入っています。

booksテーブル

>>ココナラと似てるおすすめの副業サイトを確認する

>>リモートワークもあるおすすめの転職サイトを確認する

休日で空いた時間の暇つぶしを探せるアプリを公開しています。

Contents

COUNTでレコードをカウントする

レコードの数を集計したい!って時はCOUNTを使います。

実行結果として、book_idのレコードがいくつあるか集計できますよ!

book_idのレコード数は、6なのでこれを求めるにはどうすればいいのか以下解説します。

SQL

SELECT
COUNT(book_id) as count_book
FROM
books;
// book_idのカウント
$books = Book::selectRaw('COUNT(book_id) as count_book')
         ->get();

selectRawは、select(DB::raw())の省略形です。COUNTはSQLの関数になるので、select(COUNT)とは使えません。使うには生のSQLが使えるDB::raw(‘COUNT()’)と書く必要があることに注意。

<table class="table table-striped book-list-table">
  <thead>
    <tr>
      <th>ブック数</th>
    </tr>
  </thead>
  <tbody>
    @foreach ($books as $book)
    <tr>
      <td>{{ $book->count_book }}</td>
    </tr>
    @endforeach
  </tbody>
</table>

レコード数が6と求まりました。

ユーザーごとにグループ化してブック数をカウント

レコード数をユーザーごとに集計したい場合もあるでしょう。

例えば、以下のようにuser_id=4の人はいくつ、user_id=1の人はいくつみたいな。

その場合は、グループ化させて集計します。

SELECT
user_id,
COUNT(book_id) as count_book
FROM
books
GROUP BY
user_id;
// ユーザーごとにグループ化してbook_idのカウント
$books = Book::select('user_id')
         ->selectRaw('COUNT(book_id) as count_book')
         ->groupBy('user_id')
         ->get();
<table class="table table-striped book-list-table">
  <thead>
    <tr>
      <th>ユーザー</th>
      <th>ブック数</th>
    </tr>
  </thead>
  <tbody>
    @foreach ($books as $book)
    <tr>
      <td>{{ $book->user_id }}</td>
      <td>{{ $book->count_book }}</td>
    </tr>
    @endforeach
  </tbody>
</table>

以下のようにユーザーごとにグループ化してカウントできました。

重複するレコードをカウントする場合

重複するレコードをカウントする場合は、COUNT関数とDISTINCTを併用します。

そもそもDISTINCTはSQLの知識なので詳細は、SQL DISTINCTで検索してもらえればと思うのですが、要は重複レコードを1つにまとめる機能があります。

例えば、カテゴリーとサブカテゴリーテーブルをカテゴリーIDで外部結合し、カテゴリーテーブルのカテゴリーIDがいくつあるかカウントする場合です。

想定する結果は、カテゴリーIDの数は1ですが、ただ単に外部結合してCOUNTをすると、3になります。

重複してカウントしてしまっているのが原因なので以下のようなSQLで解決しましょう。

SQL

SELECT
COUNT(DISTINCT categories.category_id)
FROM
categories
LEFT JOIN
sub_categories
ON
categories.category_id = sub_categories.category_id
WHERE
sub_categories.category_id = 1

クエリビルダで表すとこんな感じ。

$categories = Category::selectRaw('COUNT(DISTINCT category_id) as count_category')
              ->join('categories', function($join) {
                $join->on('categories.category_id', 'sub_category.category_id');
              })
              ->where(sub_categories.category_id, 1)
              ->get();

SUMで合計値を計算

book_max_priceの合計値を求めたい場合は、SUM関数を使います。

SELECT
SUM(book_max_price) as max_price
FROM
books
// book_max_priceの合計値
$books = Book::selectRaw('SUM(book_max_price) as max_price')
         ->get();
<table class="table table-striped book-list-table">
  <thead>
    <tr>
      <th>最大合計値</th>
    </tr>
  </thead>
  <tbody>
    @foreach ($books as $book)
    <tr>
      <td>{{ $book->max_price }}</td>
    </tr>
    @endforeach
  </tbody>
</table>

以下のように合計値が求まります。

ユーザーごとにグループ化して合計値を計算する

全体の集計ではなく、ユーザーごとに集計したい場合は、ユーザーをグループ化して集計します。

以下では、user_id=4のbook_max_priceの合計、user_id=1のbook_max_priceの合計を求めていきます。

SELECT
user_id,
SUM(book_max_price) as max_price
FROM
books
GROUP BY
user_id;
// book_max_priceをユーザーごとにグループ化して合計値を計算
$books = Book::select('user_id')
         ->selectRaw('SUM(book_max_price) as max_price')
         ->groupBy('user_id')
         ->get();
<table class="table table-striped book-list-table">
  <thead>
    <tr>
      <th>ユーザー</th>
      <th>最大合計値</th>
    </tr>
  </thead>
  <tbody>
    @foreach ($books as $book)
    <tr>
      <td>{{ $book->user_id }}</td>
      <td>{{ $book->max_price }}</td>
    </tr>
    @endforeach
  </tbody>
</table>

以下のようにユーザーごとにグループ化させて合計を出せました。

AVGで平均値を求める

平均値を求めたい場合は、AVG関数を使います。

以下の例で言うと、book_max_priceの平均を求めていきましょう。
※ユーザーごとにグループ化して平均値を出していきます。

SELECT
user_id,
AVG(book_max_price) as max_price
FROM
books
GROUP BY
user_id;
// ユーザーごとにグループ化して平均値を計算
$books = Book::select('user_id')
         ->selectRaw('AVG(book_max_price) as max_price')
         ->groupBy('user_id')
         ->get();
<table class="table table-striped book-list-table">
  <thead>
    <tr>
      <th>ユーザー</th>
      <th>平均値</th>
    </tr>
  </thead>
  <tbody>
    @foreach ($books as $book)
    <tr>
      <td>{{ $book->user_id }}</td>
      <td>{{ $book->max_price }}</td>
    </tr>
    @endforeach
  </tbody>
</table>

以下のようにユーザーごとにグループ化させてbook_max_priceの平均値を出せました。

>>ココナラと似てるおすすめの副業サイトを確認する

>>リモートワークもあるおすすめの転職サイトを確認する

休日で空いた時間の暇つぶしを探せるアプリを公開しています。

スキルを売り買いするならココナラ

コメント

コメントする

CAPTCHA


Contents
閉じる