Laravel belongsToMany where doesn't have one of
21,048
You can use Eloquent's whereDoesntHave() constraint to get what you need:
// get all Videos that don't belong to category 2 and 3
Video::whereDoesntHave('categories', function($query) {
$query->whereIn('id', [2, 3]);
})->get();
Comments
-
Karl almost 2 years
I have two tables:
categories
andvideos
, I then have a pivot table for these as it's a belongsToMany relationship.What I'm trying to do is get all of the videos where there isn't a single instance of the video being in one of many categories.
e.g.
- Video 1 is in category 1, 2 and 3.
- Video 2 is in category 1 and 3.
- Video 3 is in category 1.
I want to get the video which is NOT in category 2 or 3, meaning this will return Video 3.
What I've tried so far, which doesn't give the intended result, this is because another row is still found for Video 1 and 2, as they are in Category 1:
Video::whereHas('categories', function($query) { $query->whereNotIn('category_id', [2,3]); })->take(25)->get();
The query populated from this is:
select * from `videos` where exists (select * from `categories` inner join `category_video` on `categories`.`id` = `category_video`.`category_id` where `videos`.`id` = `category_video`.`video_id` and `category_id` != ? and `category_id` != ? and `categories`.`deleted_at` is null) and `videos`.`deleted_at` is null order by `created_at` desc limit 25
-
Karl almost 7 yearsUnfortunately this is still returning the same results :/
-
jedrzej.kurylo almost 7 yearsIt can't give you the same results as it's a different query, You fetched videos that have at least one category other than 2 and 3. This one gives you videos that don't have category with id 2 or 3.
-
Karl almost 7 yearsWell obviously not the exact results, but it's still returning videos which are either in category 2 or 3, as it's found in category 1.
-
jedrzej.kurylo almost 7 yearsWhats the query youre getting?
-
Karl almost 7 yearsselect * from
videos
where not exists (select * fromcategories
inner joincategory_video
oncategories
.id
=category_video
.category_id
wherevideos
.id
=category_video
.video_id
andcategory_id
in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) andcategories
.deleted_at
is null) andvideos
.deleted_at
is null order bycreated_at
desc limit 25