ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
5 つの集約関数
Laravel Query Builder には SQL の標準集約関数に対応する 5 つのメソッドがあります:
| メソッド | SQL | 戻り値 | 用途 |
|---|---|---|---|
count() | COUNT(*) | int | 行数 |
count('col') | COUNT(col) | int | NULL を除いた行数 |
max('col') | MAX(col) | 同じ型 | 最大値 |
min('col') | MIN(col) | 同じ型 | 最小値 |
avg('col') | AVG(col) | float | 平均 |
sum('col') | SUM(col) | numeric | 合計 |
基本的な使い方
use Illuminate\Support\Facades\DB;
// 行数
$cnt = DB::table('orders')->count();
// 条件付き
$cnt = DB::table('orders')->where('status', 'paid')->count();
// 最大・最小・平均・合計
$max = DB::table('orders')->max('price');
$min = DB::table('orders')->min('price');
$avg = DB::table('orders')->avg('price');
$sum = DB::table('orders')->sum('price');
// 戻り値はスカラー
echo "件数: {$cnt}, 合計: {$sum}, 平均: " . number_format($avg, 2);
Eloquent でも同じメソッドが使える
use App\Models\Order;
// Eloquent でもまったく同じ
$cnt = Order::where('status', 'paid')->count();
$max = Order::max('price');
// リレーション経由
$user = User::find(1);
$total = $user->orders()->sum('amount'); // この user の注文合計
$cnt = $user->orders()->where('status', 'paid')->count();
// withCount で N+1 を避けてカウント
$users = User::withCount(['orders', 'comments'])->get();
foreach ($users as $u) {
echo "{$u->name}: 注文 {$u->orders_count} 件 / コメント {$u->comments_count} 件\n";
}
// withSum, withMax, withMin, withAvg もある(Laravel 8+)
$users = User::withSum('orders', 'amount')->get();
echo $users[0]->orders_sum_amount;
GROUP BY と組み合わせる
「カテゴリ毎の売上集計」のような場合は selectRaw() で集約列を明示します:
// カテゴリ別に件数・合計・平均
$rows = DB::table('orders')
->selectRaw('category_id, COUNT(*) as cnt, SUM(amount) as total, AVG(amount) as avg_amount')
->where('created_at', '>=', now()->startOfMonth())
->groupBy('category_id')
->orderByDesc('total')
->get();
foreach ($rows as $r) {
echo "category {$r->category_id}: {$r->cnt} 件 / 合計 {$r->total} / 平均 {$r->avg_amount}\n";
}
HAVING — 集約結果でフィルタ
// 売上 100 万円以上のカテゴリだけ
$rows = DB::table('orders')
->selectRaw('category_id, SUM(amount) as total')
->groupBy('category_id')
->having('total', '>=', 1000000)
->orderByDesc('total')
->get();
// havingRaw で集約関数を直接書く
$rows = DB::table('orders')
->select('category_id')
->groupBy('category_id')
->havingRaw('SUM(amount) >= ?', [1000000])
->get();
DISTINCT COUNT
// ユニークユーザー数
$uniqueUsers = DB::table('orders')->distinct()->count('user_id');
// → SELECT COUNT(DISTINCT user_id) FROM orders
// 複数列の組み合わせでユニーク
$cnt = DB::table('logs')
->select('user_id', 'session_id')
->distinct()
->count();
JOIN しての集約
// ユーザー名と注文合計を一覧
$rows = DB::table('users')
->leftJoin('orders', 'users.id', '=', 'orders.user_id')
->selectRaw('users.id, users.name, COUNT(orders.id) as order_count, COALESCE(SUM(orders.amount), 0) as total_amount')
->groupBy('users.id', 'users.name')
->orderByDesc('total_amount')
->get();
サブクエリで集約結果を参照
// 平均より高い注文を抽出
$avgAmount = DB::table('orders')->avg('amount');
$expensive = DB::table('orders')
->where('amount', '>', $avgAmount)
->get();
// 1 クエリで書きたい場合は selectSub / whereRaw
$expensive = DB::table('orders')
->whereRaw('amount > (SELECT AVG(amount) FROM orders)')
->get();
条件付き集約(CASE WHEN)
// ステータス別の件数を 1 行で取得(ピボット)
$row = DB::table('orders')
->selectRaw("
COUNT(*) as total,
SUM(CASE WHEN status = 'paid' THEN 1 ELSE 0 END) as paid_count,
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending_count,
SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) as paid_amount
")
->where('created_at', '>=', now()->subDays(30))
->first();
echo "支払い済: {$row->paid_count} 件 / 合計 {$row->paid_amount} 円";
FAQ
Q: avg() の戻り値が文字列になる
A: DB ドライバによっては精度保持のため文字列で返します。(float) $avg でキャストするか、number_format() で表示。
Q: count() でめちゃくちゃ遅い
A: MyISAM は COUNT(*) が即時ですが、InnoDB は MVCC のためフルスキャンが発生します。インデックスをカバーするカウントにするか、概算でよければ SHOW TABLE STATUS。
Q: groupBy 後に paginate したい
A: 通常の paginate() は count クエリが GROUP BY を理解できず壊れます。simplePaginate() か手動で OFFSET/LIMIT を計算してください。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
同階層のページ
- SELECT
- INSERT
- UPDATE
- DELETE
- order by句のキャスト
- count / max / average (集計)
- 配列を条件にする方法
- where句の入れ子(ネスト)
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Laravel キャッシュクリア完全ガイド(cache:clear / config:clear / 2026-05-18 07:42:07
- プロジェクトの作成と削除 2026-05-18 07:42:07
- インストール直後にNetbeansが反応しない 2026-05-18 07:42:07
- 動画やチャンネルの検索 2026-05-18 07:42:07
- APIキー取得方法 2026-05-18 07:42:07
- チャンネル情報の取得 2026-05-18 07:42:07
- API 入門 — Web API(REST / GraphQL / gRPC / 2026-05-18 07:42:07
- インストール(eclipseプラグイン) 2026-05-18 07:42:07
- Laravel「Dotenv values containing spaces must be surrounded 2026-05-18 07:42:07
- エラー一覧 2026-05-18 07:42:07
- curl: (51) SSL: certificate subject name '~' does not match 2026-05-18 07:42:07
- インストール方法(Windows版) 2026-05-18 07:42:07
- JSONから配列に変換 2026-05-18 07:42:07
- 処理を一定時間待つ 2026-05-18 07:42:07
- A non well formed numeric value encountered 2026-05-18 07:42:07
コメントを削除してもよろしいでしょうか?