I have a scope which picks out the first result per group for a set of results.
public function scopeFirstPerGroup(Builder $query, ?array $fields = null, string $by = 'id'): Builder
{
return $query->whereIn('id', function (QueryBuilder $queryBuilder) use ($fields, $by, $query) {
return $queryBuilder->from(static::getTable())
->selectRaw("min(`$by`)")
->groupBy($fields ?? static::$groupedScopeFields);
});
}
This works, but it does not take into account any other conditions that were setup in the parent query. For example, the generated SQL output is:
select * from `queue_jobs` where `started_at` is null and `id` in (select min(`id`) from `queue_jobs` group by `throttle_groups`) order by `id` asc
But when the following whereNull is added to the parent query:
QueueJob::orderBy('id')
->whereNull('started_at')
->firstPerGroup(['throttle_groups'])
->get();
It should instead be:
select * from `queue_jobs` where `started_at` is null and `id` in (select min(`id`) from `queue_jobs` WHERE `started_at` IS NULL group by `throttle_groups`) order by `id` asc
Within the scope I need to somehow get the whereNull('started_at') (along with any other conditionals that may be added in. I somehow need to get these conditionals into the commented line below, but am unsure how.
public function scopeFirstPerGroup(Builder $query, ?array $fields = null, string $by = 'id'): Builder
{
return $query->whereIn('id', function (QueryBuilder $queryBuilder) use ($fields, $by, $query) {
return $queryBuilder->from(static::getTable())
//->where... (I need to add in the the whereNull and whereType from parent query)
->selectRaw("min(`$by`)")
->groupBy($fields ?? static::$groupedScopeFields);
});
}