【Laravel】サブクエリを使った高度な検索方法|whereIn・selectRawの使い分け

【Laravel】サブクエリを使った高度な検索方法|whereIn・selectRawの使い分け Laravel

LaravelのEloquentやクエリビルダを使って開発を進めていると、単純な検索だけでなく「特定条件に一致するレコードだけを抽出したい」という複雑な要件に出くわすことがあります。そんなときに役立つのが「サブクエリ」です。

本記事では、Laravelでサブクエリを用いた検索機能を実装する方法を、whereIn()とselectRaw()を軸に解説します。

サブクエリとは何か?

サブクエリ(副問い合わせ)とは、クエリの中に別のクエリを内包して条件に使うSQLの書き方です。LaravelではクエリビルダやEloquentを通じて、SQLを直書きせずにサブクエリを表現することができます。

たとえば「投稿数が5件以上あるユーザーの一覧」など、通常のリレーションでは書きにくい条件を扱うときに効果を発揮します。

whereInによるサブクエリの活用例

まずはwhereIn()を使って、投稿数が一定以上あるユーザーを取得する例を見てみましょう。

use Illuminate\Support\Facades\DB;

$users = DB::table('users')
    ->whereIn('id', function ($query) {
        $query->select('user_id')
            ->from('posts')
            ->groupBy('user_id')
            ->havingRaw('COUNT(*) >= 5');
    })
    ->get();

このコードでは、投稿数が5件以上のユーザーIDをpostsテーブルから取得し、それに該当するユーザーのみをusersテーブルから抽出しています。

whereInは配列も受け取れますが、このようにサブクエリを与えることで、より動的で強力な絞り込みが可能になります。

selectRawによるサブクエリの利用

次に、selectRaw()を使ってサブクエリの結果をカラムとして取得する例です。たとえば、各ユーザーの投稿数を一覧に含めたいとします。

$users = DB::table('users')
    ->select('users.*')
    ->selectRaw('(SELECT COUNT(*) FROM posts WHERE posts.user_id = users.id) as post_count')
    ->get();

この例では、ユーザー情報とあわせて、投稿数(post_count)をサブクエリで算出して取得しています。

このようにselectRaw()は「集計値や計算値を追加したい」「表示用にサブクエリの値を取得したい」といったケースで便利です。

Eloquentでも同様に使える

クエリビルダだけでなく、Eloquentモデルを使っても同様のサブクエリが可能です。

whereIn + モデル

use App\Models\User;

$users = User::whereIn('id', function ($query) {
    $query->select('user_id')
        ->from('posts')
        ->groupBy('user_id')
        ->havingRaw('COUNT(*) >= 5');
})->get();

selectRaw + モデル

$users = User::select('*')
    ->selectRaw('(SELECT COUNT(*) FROM posts WHERE posts.user_id = users.id) as post_count')
    ->get();

Laravelのモデルを使えば、後続の処理やビューへの渡し方も自然で、読みやすいコードになります。

サブクエリを使うときの注意点

サブクエリは便利な反面、以下のような注意点もあります。

  • パフォーマンスに注意:サブクエリ内でJOINやGROUP BYを多用すると重くなることがあるため、インデックス設計やキャッシュの併用を検討してください。
  • Eloquentリレーションと併用が難しいケースあり:Eager Loading(with())などと併用する場合、整合性に注意が必要です。
  • MySQL・PostgreSQLなどDBによって挙動差あり:サブクエリの挙動はDBごとに違いがあるので、環境に合わせてテストしましょう。

まとめ:Laravelでのサブクエリは柔軟な検索を可能にする強力な武器

Laravelでは、whereIn()やselectRaw()を使うことで、サブクエリを柔軟に活用できます。複雑な検索要件や動的なデータ集計を実現したいときには、積極的に活用してみましょう。

さらに発展的には、joinSub()やfromSub()といった方法もあり、ビューやランキング表示などにも応用が可能です。ニーズに応じて使い分けることで、Laravelの検索処理はよりパワフルなものになります。