雄辩的按关系过滤(仅最后一条记录)

时间:2019-09-25 14:48:17

标签: mysql laravel eloquent relationship has-many

我将问题编辑为更明确

我需要建立一个范围来过滤hasMany关系。问题是,我想将该查询应用于最后,我的意思是,我希望通过HasMany关系的特定记录的列过滤我的模型,是有可能吗?

上下文:具有帖子的应用程序,每个帖子都有许多状态来保持历史。我想按每个帖子的最后状态来过滤帖子。

帖子:

{
    public function statuses() 
    {
        return $this->hasMany(Status::class); // Only last one is important for querying
    }
}

然后,在范围内,我想做这样的事情:

public function scopeIsActive(Builder $builder)
{
    return $builder->whereHas('statuses', function(Builder $q) {
        // How to apply this ONLY to last created record???
        return $q->whereDate('activation', '<=', today());
    });
}

仅此而已!

编辑:(已解决查询)

经过一番挖掘,我解决了这个问题:

public function scopeIsActive(Builder $builder)
{
    return $builder->whereHas('statuses', function (Builder $q) {
        return $q->whereDate('activation', '<=', today()) // applies to all
            ->where('statuses.id', function ($sub) { // applies to specific one
            return $sub->select('id')
                ->from('statuses')
                ->whereColumn('post_id', 'statuses.id')
                ->latest()
                ->limit(1);
        });
    });
}

3 个答案:

答案 0 :(得分:2)

代替

public function others() 
{
    return $this->hasMany(Other::class); // Only last one is important for querying
}

您可以这样做:


public function other() 
{
    return $this->hasOne(Other::class)->latest();querying
}

然后

public function scopeCurrentActive(Builder $builder)
{
    return $builder->whereHas('other', function(Builder $q) {
        return $q->whereDate('activation', '<=', today());
    });
}

但是您不能下定单,如果要下定单,则必须使用子查询:

return Model::orderByDesc(
    Other::select('arrived_at')
        ->whereColumn('model_id', 'model.id')
        ->orderBy('activation', 'desc')
        ->limit(1)
)->get();

如果您想了解有关子查询的更多信息,可以参考:

https://laravel-news.com/eloquent-subquery-enhancements

对于仅使用最后一条记录,您可能必须使用诸如以下这样的hading语句,但是我不确定确切的合奏^^


public function scopeIsActive(Builder $builder)
{
    return $builder->whereHas('statuses', function (Builder $q) {
        return $q->havingRaw(Other::select('arrived_at')
        ->whereColumn('model_id', 'model.id')
        ->orderBy('activation', 'desc')
        ->limit(1)->select('activation')->toSql(), '<=' , today());
    });
}

答案 1 :(得分:0)

按今天激活的项目过滤:

df[endsWith(tolower(df$b), "c"),]
#OR
df[grepl(".*c$", df$b, ignore.case = TRUE),]
#OR
df[substring(df$b, nchar(df$b), nchar(df$b)) %in% c("c", "C"),]
#  a  b
#1 1 aC
#3 3 ac

答案 2 :(得分:0)

不确定每个最后一条记录的确切含义

在这里,您可以获取状态与最新帖子相同的所有帖子:

public function scopeIsActive(Builder $builder)
{
    $lastPostStatus = Post::select('status')
        ->orderBy('activation', 'desc')
        ->first()
        ->status;

    return $builder->where('status', $lastPostStatus);
}