Documentation Index Fetch the complete documentation index at: https://kawax.biz/llms.txt
Use this file to discover all available pages before exploring further.
クエリビルダーとは
Laravelのクエリビルダーは、データベースクエリを流暢なインターフェースで構築・実行する仕組みです。DB ファサードの table() メソッドから始まり、メソッドチェーンでクエリを組み立てます。
use Illuminate\Support\Facades\ DB ;
$users = DB :: table ( 'users' ) -> get ();
内部ではPDOパラメーターバインディングを使用しているため、SQLインジェクション対策が自動的に行われます。
クエリビルダーはLaravelがサポートするすべてのデータベース(MySQL、MariaDB、PostgreSQL、SQLite、SQL Server)で動作します。データベースを切り替えても同じコードが使えます。
Eloquentとの使い分け
状況 推奨 モデルとリレーションが必要 Eloquent 複雑な集計やレポート クエリビルダー パフォーマンスが重要な大量データ処理 クエリビルダー 既存テーブルへのシンプルな操作 クエリビルダー マイグレーションやシーダー内の処理 クエリビルダー
データの取得
全件取得
$users = DB :: table ( 'users' ) -> get ();
foreach ( $users as $user ) {
echo $user -> name ;
}
get() は Illuminate\Support\Collection を返します。各レコードはPHPの stdClass オブジェクトです。
1件取得
// 最初の1件を取得(見つからなければ null)
$user = DB :: table ( 'users' ) -> where ( 'name' , '山田太郎' ) -> first ();
// 見つからなければ例外を投げる(404レスポンスを自動返却)
$user = DB :: table ( 'users' ) -> where ( 'name' , '山田太郎' ) -> firstOrFail ();
// 特定カラムの値のみ取得
$email = DB :: table ( 'users' ) -> where ( 'name' , '山田太郎' ) -> value ( 'email' );
// IDで取得
$user = DB :: table ( 'users' ) -> find ( 3 );
特定カラムの値をリストで取得
// emailカラムの値のコレクション
$emails = DB :: table ( 'users' ) -> pluck ( 'email' );
// nameをキー、emailを値とする連想コレクション
$emailByName = DB :: table ( 'users' ) -> pluck ( 'email' , 'name' );
大量データの分割処理
use Illuminate\Support\ Collection ;
// 100件ずつ処理
DB :: table ( 'users' ) -> orderBy ( 'id' ) -> chunk ( 100 , function ( Collection $users ) {
foreach ( $users as $user ) {
// 処理...
}
});
// 更新しながらチャンク処理する場合は chunkById を使う
DB :: table ( 'users' ) -> where ( 'active' , false )
-> chunkById ( 100 , function ( Collection $users ) {
foreach ( $users as $user ) {
DB :: table ( 'users' )
-> where ( 'id' , $user -> id )
-> update ([ 'active' => true ]);
}
});
チャンク処理中にレコードを更新・削除する場合、chunk() ではなく chunkById() を使ってください。chunk() ではレコードのずれが生じることがあります。
ストリーミング(LazyCollection)
DB :: table ( 'users' ) -> orderBy ( 'id' ) -> lazy () -> each ( function ( object $user ) {
// 1件ずつ処理
});
$count = DB :: table ( 'users' ) -> count ();
$maxAge = DB :: table ( 'users' ) -> max ( 'age' );
$minAge = DB :: table ( 'users' ) -> min ( 'age' );
$avgAge = DB :: table ( 'users' ) -> avg ( 'age' );
$total = DB :: table ( 'orders' ) -> sum ( 'amount' );
// 条件付き集計
$avgPremium = DB :: table ( 'orders' )
-> where ( 'plan' , 'premium' )
-> avg ( 'amount' );
レコードの存在確認
if ( DB :: table ( 'orders' ) -> where ( 'finalized' , 1 ) -> exists ()) {
// レコードが存在する
}
if ( DB :: table ( 'orders' ) -> where ( 'finalized' , 1 ) -> doesntExist ()) {
// レコードが存在しない
}
SELECT句
// 取得するカラムを指定
$users = DB :: table ( 'users' )
-> select ( 'name' , 'email as user_email' )
-> get ();
// 重複を除外
$users = DB :: table ( 'users' ) -> distinct () -> get ();
// 後からカラムを追加
$query = DB :: table ( 'users' ) -> select ( 'name' );
$users = $query -> addSelect ( 'age' ) -> get ();
WHERE句
基本的な条件
// 等値条件(= は省略可能)
$users = DB :: table ( 'users' ) -> where ( 'votes' , 100 ) -> get ();
// 比較演算子を指定
$users = DB :: table ( 'users' ) -> where ( 'votes' , '>=' , 100 ) -> get ();
$users = DB :: table ( 'users' ) -> where ( 'name' , 'like' , '山田%' ) -> get ();
// 複数条件(AND)
$users = DB :: table ( 'users' )
-> where ( 'status' , 'active' )
-> where ( 'age' , '>' , 20 )
-> get ();
// OR条件
$users = DB :: table ( 'users' )
-> where ( 'votes' , '>' , 100 )
-> orWhere ( 'name' , '山田太郎' )
-> get ();
条件のグループ化
use Illuminate\Database\Query\ Builder ;
// OR条件をグループ化してANDと組み合わせる
$users = DB :: table ( 'users' )
-> where ( 'active' , true )
-> where ( function ( Builder $query ) {
$query -> where ( 'role' , 'admin' )
-> orWhere ( 'role' , 'moderator' );
})
-> get ();
// WHERE active = 1 AND (role = 'admin' OR role = 'moderator')
whereIn / whereBetween / whereNull
// IN句
$users = DB :: table ( 'users' )
-> whereIn ( 'id' , [ 1 , 2 , 3 ])
-> get ();
$users = DB :: table ( 'users' )
-> whereNotIn ( 'id' , [ 1 , 2 , 3 ])
-> get ();
// BETWEEN句
$users = DB :: table ( 'users' )
-> whereBetween ( 'age' , [ 20 , 40 ])
-> get ();
// NULL判定
$users = DB :: table ( 'users' ) -> whereNull ( 'deleted_at' ) -> get ();
$users = DB :: table ( 'users' ) -> whereNotNull ( 'email_verified_at' ) -> get ();
whereLike(パターンマッチ)
// デフォルトは大文字小文字を区別しない
$users = DB :: table ( 'users' )
-> whereLike ( 'name' , '%山田%' )
-> get ();
// 大文字小文字を区別する
$users = DB :: table ( 'users' )
-> whereLike ( 'name' , '%Yamada%' , caseSensitive : true )
-> get ();
whereAny / whereAll(複数カラムへの同一条件)
// いずれかのカラムがLIKE条件にマッチ
$users = DB :: table ( 'users' )
-> where ( 'active' , true )
-> whereAny ([ 'name' , 'email' , 'bio' ], 'like' , '%Laravel%' )
-> get ();
// すべてのカラムがLIKE条件にマッチ
$posts = DB :: table ( 'posts' )
-> whereAll ([ 'title' , 'content' ], 'like' , '%Laravel%' )
-> get ();
JOIN
// INNER JOIN
$users = DB :: table ( 'users' )
-> join ( 'orders' , 'users.id' , '=' , 'orders.user_id' )
-> select ( 'users.name' , 'orders.amount' )
-> get ();
// LEFT JOIN
$users = DB :: table ( 'users' )
-> leftJoin ( 'orders' , 'users.id' , '=' , 'orders.user_id' )
-> get ();
// 複数テーブルのJOIN
$users = DB :: table ( 'users' )
-> join ( 'contacts' , 'users.id' , '=' , 'contacts.user_id' )
-> join ( 'orders' , 'users.id' , '=' , 'orders.user_id' )
-> select ( 'users.*' , 'contacts.phone' , 'orders.amount' )
-> get ();
サブクエリJOIN
// サブクエリを使ったJOIN
$latestOrders = DB :: table ( 'orders' )
-> select ( 'user_id' , DB :: raw ( 'MAX(created_at) as last_order_at' ))
-> groupBy ( 'user_id' );
$users = DB :: table ( 'users' )
-> joinSub ( $latestOrders , 'latest_orders' , function ( $join ) {
$join -> on ( 'users.id' , '=' , 'latest_orders.user_id' );
})
-> get ();
並び替え・グループ化・リミット
// 並び替え
$users = DB :: table ( 'users' )
-> orderBy ( 'name' , 'asc' )
-> get ();
// 複数カラムで並び替え
$users = DB :: table ( 'users' )
-> orderBy ( 'last_name' )
-> orderBy ( 'first_name' , 'desc' )
-> get ();
// ランダム順
$users = DB :: table ( 'users' ) -> inRandomOrder () -> get ();
// グループ化
$orders = DB :: table ( 'orders' )
-> select ( 'status' , DB :: raw ( 'COUNT(*) as count' ))
-> groupBy ( 'status' )
-> get ();
// HAVING句
$orders = DB :: table ( 'orders' )
-> select ( 'user_id' , DB :: raw ( 'SUM(amount) as total' ))
-> groupBy ( 'user_id' )
-> having ( 'total' , '>' , 10000 )
-> get ();
// リミットとオフセット
$users = DB :: table ( 'users' )
-> skip ( 10 ) // OFFSET
-> take ( 5 ) // LIMIT
-> get ();
サブクエリ
// WHERE句のサブクエリ
$activeUsers = DB :: table ( 'users' ) -> select ( 'id' ) -> where ( 'is_active' , 1 );
$comments = DB :: table ( 'comments' )
-> whereIn ( 'user_id' , $activeUsers )
-> get ();
// SELECT句のサブクエリ
$users = DB :: table ( 'users' )
-> select ( 'name' )
-> selectSub ( function ( $query ) {
$query -> from ( 'orders' )
-> selectRaw ( 'COUNT(*)' )
-> whereColumn ( 'orders.user_id' , 'users.id' );
}, 'order_count' )
-> get ();
Raw式
Raw式はSQL文字列として直接クエリに挿入されます。ユーザー入力を直接渡すとSQLインジェクションの危険があります。必ずバインディングを使って安全に記述してください。
// DB::raw() — 任意のSQL式を埋め込む
$users = DB :: table ( 'users' )
-> select ( DB :: raw ( 'count(*) as user_count, status' ))
-> groupBy ( 'status' )
-> get ();
// selectRaw — SELECT句にRaw式を追加
$orders = DB :: table ( 'orders' )
-> selectRaw ( 'price * ? as price_with_tax' , [ 1.10 ])
-> get ();
// whereRaw — WHERE句にRaw式を追加
$orders = DB :: table ( 'orders' )
-> whereRaw ( 'price > IF(state = "JP", ?, 100)' , [ 500 ])
-> get ();
// havingRaw — HAVING句にRaw式を追加
$orders = DB :: table ( 'orders' )
-> select ( 'department' , DB :: raw ( 'SUM(amount) as total' ))
-> groupBy ( 'department' )
-> havingRaw ( 'SUM(amount) > ?' , [ 100000 ])
-> get ();
// orderByRaw — ORDER BY句にRaw式を追加
$orders = DB :: table ( 'orders' )
-> orderByRaw ( 'updated_at - created_at DESC' )
-> get ();
INSERT / UPDATE / DELETE
INSERT
// 1件挿入
DB :: table ( 'users' ) -> insert ([
'email' => '[email protected] ' ,
'name' => '山田太郎' ,
]);
// 複数件挿入
DB :: table ( 'users' ) -> insert ([
[ 'email' => '[email protected] ' , 'name' => '山田太郎' ],
[ 'email' => '[email protected] ' , 'name' => '鈴木花子' ],
]);
// 挿入後にAUTO_INCREMENTのIDを取得
$id = DB :: table ( 'users' ) -> insertGetId ([
'email' => '[email protected] ' ,
'name' => '佐藤次郎' ,
]);
UPSERT(INSERT OR UPDATE)
// 存在すれば更新、なければ挿入
DB :: table ( 'users' ) -> upsert (
[
[ 'email' => '[email protected] ' , 'name' => '山田太郎' , 'votes' => 5 ],
[ 'email' => '[email protected] ' , 'name' => '鈴木花子' , 'votes' => 10 ],
],
uniqueBy : [ 'email' ], // 重複チェックのカラム
update : [ 'name' , 'votes' ] // 更新するカラム
);
UPDATE
// 条件付き更新
$affected = DB :: table ( 'users' )
-> where ( 'id' , 1 )
-> update ([ 'name' => '山田一郎' , 'updated_at' => now ()]);
// インクリメント・デクリメント
DB :: table ( 'users' ) -> where ( 'id' , 1 ) -> increment ( 'votes' ); // +1
DB :: table ( 'users' ) -> where ( 'id' , 1 ) -> increment ( 'votes' , 5 ); // +5
DB :: table ( 'users' ) -> where ( 'id' , 1 ) -> decrement ( 'votes' ); // -1
DB :: table ( 'users' ) -> where ( 'id' , 1 ) -> decrement ( 'balance' , 100 ); // -100
DELETE
// 条件付き削除
$deleted = DB :: table ( 'users' ) -> where ( 'status' , 'inactive' ) -> delete ();
// テーブル全件削除(AUTO_INCREMENTをリセット)
DB :: table ( 'users' ) -> truncate ();
条件付きクエリ(when)
クエリ条件を動的に適用したいときは when() を使うと条件分岐をすっきり書けます。
$status = request ( 'status' );
$sortBy = request ( 'sort' , 'name' );
$users = DB :: table ( 'users' )
-> when ( $status , function ( $query , $status ) {
$query -> where ( 'status' , $status );
})
-> when ( $sortBy === 'email' , function ( $query ) {
$query -> orderBy ( 'email' );
}, function ( $query ) {
$query -> orderBy ( 'name' );
})
-> get ();
デバッグ
// 生成されるSQLを確認
$sql = DB :: table ( 'users' ) -> where ( 'active' , true ) -> toSql ();
// "select * from `users` where `active` = ?"
// SQLとバインディングを両方確認
$bindings = DB :: table ( 'users' ) -> where ( 'active' , true ) -> getBindings ();
// クエリを実行してダンプ(実行は続行)
DB :: table ( 'users' ) -> where ( 'active' , true ) -> dump ();
// クエリを実行してダンプして終了
DB :: table ( 'users' ) -> where ( 'active' , true ) -> dd ();
dd() はデバッグ時に便利ですが、本番環境では絶対に使わないでください。toSql() と getBindings() でSQLとバインディングを確認するのが安全です。
まとめ
メソッド 説明 get()全件取得(Collection) first()最初の1件取得 find($id)IDで1件取得 value($column)カラムの値を1件取得 pluck($column)カラム値のリストを取得 count()件数 sum($col)合計 avg($col)平均 max($col)最大値 min($col)最小値 exists()存在確認 insert([...])挿入 update([...])更新 delete()削除 chunk($n, fn)分割して処理 when($cond, fn)条件付きクエリ toSql()生成SQLを確認
クエリビルダーはEloquentよりも低レベルで、モデルのインスタンスではなく stdClass を返します。
リレーションやモデルイベント(オブザーバー)が不要な場合、クエリビルダーの方がシンプルで高速です。 // Eloquent: Userモデルのインスタンスを返す
$users = User :: where ( 'active' , true ) -> get ();
echo $users [ 0 ] -> name ; // Userオブジェクト
// クエリビルダー: stdClassを返す
$users = DB :: table ( 'users' ) -> where ( 'active' , true ) -> get ();
echo $users [ 0 ] -> name ; // stdClassオブジェクト