LaravelでDBからデータを取得する際に、OR条件でデータを取得する方法を紹介します。
OR検索
OR検索をする場合は、where()の後にorWhere()を使います。
$posts = Post::where('slug', 'post1')
->orWhere('slug', 'post2')
->get();
発行される SQL は以下のようになります。
select * from `posts` where `slug` = ? or `slug` = ?
AND条件と組み合わせる
A and (B or C) のような他のAND条件を組み合わせる場合は、where()の中にクロージャを使ってまとめます。
$posts = Post::where('category', 'PHP')
->where(function(Builder $query){
$query->where('slug', 'post1')
->orWhere('slug', 'post2');
})
->get();
発行される SQL は以下のようになります。 ORを含むAND条件がカッコで囲まれていることがわかります。
select * from `posts` where `category` = ? and (`slug` = ? or `slug` = ?)
変数を使う場合
where()内で変数を使う場合は、use()で変数を渡します。
$posts = Post::where('category', 'PHP')
->where(function(Builder $query) use($slug1, $slug2){
$query->where('slug', $slug1)
->orWhere('slug', $slug2);
})
->get();
リレーション先のカラムで検索
リレーション先のカラムで検索する場合は、特に注意が必要です。
以下の例では、PostモデルにリレーションしているCommentモデルのuser_idで検索していますが、意図しない結果になる可能性があります。
!NG例です
$post = Post::find(1);
$posts = $post->comments()
->where('user_id', 1)
->orWhere('user_id', 2)
->get();
発行される SQL は以下のようになります。リレーションのAND条件が付与されるため、OR条件が他のAND条件に影響を与えてしまいます。
select * from `comments` where `comments`.`post_id` = ? and `comments`.`post_id` is not null and `user_id` = ? or `user_id` = ?
リレーション先のカラムでOR条件を使う場合は、where()の中にクロージャを使ってまとめるようにします。
$posts = $post->comments()
->where(function(Builder $query){
$query->where('user_id', 1)
->orWhere('user_id', 2);
})
->get();
select * from `comments` where `comments`.`post_id` = ? and `comments`.`post_id` is not null and (`user_id` = ? or `user_id` = ?)
以上、OR条件でデータを取得する方法でした。意図しない結果にならないように確認が大事ですね。