【Laravel】whereをネストする方法を解説

Laravelは直感的かつ簡単にデータベース操作が行えることが特徴です。しかし、条件が複雑なクエリを構築する際には、where句をネストする必要が出てくることがあります。例えば、「特定のステータスを持つユーザーの中で、複数の役職を持つ人を検索したい」といった場合です。

本記事では、Laravelでwhere句をネストする方法をわかりやすく解説し、実用的なサンプルコードを交えながら活用方法をご紹介します。これにより、柔軟で読みやすいクエリを構築できるようになりますので、ぜひ参考にしてください!

ネストしたwhereの基本構文

Laravelのクエリビルダを使用すると、where 句をネストして、複雑な条件を簡潔に表現できます。

例えば、「ステータスが active で、役職が admin または editor であるユーザー」を取得したい場合、次のように書くことができます。

$users = User::where('status', 'active')
            ->where(function ($query) {
                $query->where('role', 'admin')
                      ->orWhere('role', 'editor');
            })
            ->get();

この構文を理解しておくことで、複雑なクエリも直感的に記述できるようになります。

実用例1:複数のOR条件を持つクエリ

実務では、特定の条件を満たすデータをOR 条件でフィルタリングするシナリオがよくあります。例えば、「ステータスが active で、役職が admin または editor または author であるユーザー」を取得したい場合、以下のように記述できます。

$users = User::where('status', 'active')
            ->where(function ($query) {
                $query->where('role', 'admin')
                      ->orWhere('role', 'editor')
                      ->orWhere('role', 'author');
            })
            ->get();

実際に実行されるSQLクエリ

上記のコードが生成するSQLは以下のようになります。

SELECT *
FROM users 
WHERE status = 'active' 
  AND (role = 'admin' OR role = 'editor' OR role = 'author');

応用例

このアプローチを応用することで、他のフィルタ条件やテーブル結合と組み合わせることも可能です。例えば、特定の日付範囲内で作成されたユーザーをさらに絞り込むことも簡単です。

$users = User::where('status', 'active')
            ->where(function ($query) {
                $query->where('role', 'admin')
                      ->orWhere('role', 'editor')
                      ->orWhere('role', 'author');
            })
            ->whereBetween('created_at', ['2024-01-01', '2024-12-31'])
            ->get();

このように、where のネストを活用することで、柔軟かつ複雑な条件を持つクエリを簡潔に記述できます。次のセクションでは、ANDOR 以外の条件を組み合わせた例をご紹介します。

日付範囲と他の条件の組み合わせ

業務では、特定の期間内のデータを条件に加えるケースがよくあります。例えば、「ステータスが acitve で、作成日または更新日が特定の期間内に該当するユーザー」を取得したい場合、以下のように記述できます。

$users = User::where(function ($query) {
                $query->whereBetween('created_at', ['2024-01-01', '2024-12-31'])
                      ->orWhereBetween('updated_at', ['2024-01-01', '2024-12-31']);
            })
            ->where('status', 'active')
            ->get();

実行されるSQLクエリ

このコードが生成するSQLは以下のようになります。

SELECT * 
FROM users 
WHERE (created_at BETWEEN '2024-01-01' AND '2024-12-31' 
       OR updated_at BETWEEN '2024-01-01' AND '2024-12-31')
  AND status = 'active';

このように、where のネストを活用すると、期間の条件や他の属性を組み合わせた複雑なクエリを簡潔に書くことができます。

whereクロージャ内で外部の変数を参照する方法

Laravelでクエリビルダを使用する際、クロージャ内で外部の変数を参照する場合にはuse キーワードを使用します。これにより、スコープの外にある変数をクロージャ内に渡すことができます。

public function scopeActiveInRange($query, $startDate, $endDate)
{
    return $query->where('status', 'active')
                 ->where(function ($query) use ($startDate, $endDate) {
                     $query->whereBetween('created_at', [$startDate, $endDate])
                           ->orWhereBetween('updated_at', [$startDate, $endDate]);
                 });
}

useが必要な理由

クロージャ(無名関数)は通常、定義されたスコープ内の変数に直接アクセスできません。そのため、クロージャの外にある変数を使用する場合、use キーワードを明示的に指定して渡す必要があります。

上記のコードでは、$startDate$endDate をクロージャに渡すことで、日付範囲を指定した条件をクエリに追加しています。

use を適切に使いこなすことで、より柔軟で再利用可能なクエリやスコープメソッドを構築できるようになります。

まとめ

Laravelのクエリビルダにおけるwhereのネストは、複雑な条件を柔軟に記述できる強力な機能です。その中でも、クロージャを使った条件のグループ化やuseキーワードの活用は、コードの読みやすさと保守性を高める重要なポイントとなります。

今回紹介した内容を実際のプロジェクトで試しながら、適切に活用してみましょう。特に複雑な条件を扱う場合、whereのネストとuseを組み合わせることで、柔軟性と効率性を実感できるはずです。

クエリの構築力をさらに高めるために、他のEloquentのメソッドやデバッグツールも積極的に学んでいきましょう!

コメント