ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子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アノテーションとは
最近更新/作成されたページ
- SEO タイトル設計とキーワード配置完全ガイド (CTR / LLMO 対応) 2026-06-10 18:13:56
- Vue.js v-bind 完全ガイド (属性 / クラス / スタイル / Composition API) 2026-06-10 18:13:56
- Twitter (X) プラットフォーム完全ガイド 2026 (API / Premium / 競合) 2026-06-10 18:13:56
- PHP 変数スコープ完全ガイド (global / static / use / Arrow Function) 2026-06-10 18:13:56
- jQuery .height() 完全ガイド (innerHeight / outerHeight / box-sizing) 2026-06-10 18:13:56
- WordPress 主要独自関数完全ガイド (Loop / Enqueue / Hook / Conditional Tag) 2026-06-10 18:13:56
- jQuery 要素・値の削除完全ガイド (remove / detach / empty / val) 2026-06-10 18:13:56
- PHP コメント完全ガイド (// / # / /* */ / PHPDoc) 2026-06-10 18:13:56
- PHP 改行出力 (\n / PHP_EOL / nl2br) 完全ガイド 2026-06-10 18:13:56
- JavaScript 確認ダイアログ完全ガイド (confirm / alert / prompt / dialog) 2026-06-10 18:13:56
- UE5 スクリーンショット保存 (Scene Capture) 完全ガイド 2026-06-10 18:12:53
- UE5 Nav Mesh Bounds Volume 完全ガイド 2026-06-10 18:12:53
- EJS テンプレートの共通化 (include) 完全ガイド 2026-06-10 18:12:53
- UE5 カメラ傾き角度制限完全ガイド (Pitch Min/Max) 2026-06-10 18:12:53
- SQLite 完全ガイド (組み込み RDBMS) 2026-06-10 18:12:53
コメントを削除してもよろしいでしょうか?