Laravel HasMany 查询最新入口并返回相关模型

Posted

技术标签:

【中文标题】Laravel HasMany 查询最新入口并返回相关模型【英文标题】:Laravel HasMany query latest entry and return related model 【发布时间】:2021-02-02 07:33:47 【问题描述】:

使用 Laravel 8

我有 3 个模型(专辑、曲目、播放次数)。一张专辑有很多曲目,而一个曲目有很多播放计数(每 24 小时运行一次作业并更新播放计数)。

专辑模型

public function playcounts()

    return $this->hasManyThrough('App\Models\Playcount', 'App\Models\Track');

跟踪模型

public function playcounts()

    return $this->hasMany(Playcount::class, 'track_id');

播放次数模型

public function track()

    return $this->belongsTo(Track::class);

我希望能够选择播放计数表中 LATEST 条目超过 24 小时的所有专辑。被困在这几天了。 我现在正在尝试的是:

播放次数模型

public function latest_playcount()
    
        return $this->playcounts()->latest()->first();
    

控制器

$track = Track::whereHas('playcounts', function($q) 
    $q->where('created_at', '<=', Carbon::now()->subHour(24));
        )
        ->with('playcounts')
        ->first();

$album_id = $track->album_id; //after this, select the album

是否可以在一个查询中执行此操作?

非常感谢任何帮助。

编辑:如果有人遇到类似的事情,我是这样解决的:

$album = DB::table('playcounts as p')
          ->select('p.*')
          ->leftJoin('playcounts as p1', function ($join) 
                $join->on('p.track_id', '=', 'p1.track_id')
                     ->whereRaw(DB::raw('p.created_at < p1.created_at'));
           )
          ->whereNull('p1.track_id')
          ->where('p.created_at', '<=', Carbon::now()->subHours(24))
                  ->join('tracks', 'tracks.id', 'p.track_id')
                    ->join('albums', 'albums.id', 'tracks.album_id')
                    ->addSelect('albums.*')
                    ->groupBy('albums.id')
                  ->take(1)->get();

感谢大家的帮助!

【问题讨论】:

为什么不从播放次数开始,然后回到专辑? 不知道我理解的对不对,你要最近24小时播放过的专辑吗? 您好 Artur,我希望所有专辑的曲目在 playcounts 表中的 LATEST 条目早于 24 小时。问题是只识别每个轨道的最新条目 【参考方案1】:

根据我的评论,你试过这个吗?

我假设您的表被命名为: tracks, albums, playcounts

而且它们都有列名,我已经列出了。

use DB;

$albums = Playcount::where('created_at', '<=', Carbon::now()->subDay())
    ->join('tracks', 'tracks.id', 'playcounts.track_id')
    ->join('albums', 'albums.id', 'tracks.album_id')
    ->addSelect(DB::raw('albums.*, SUM(playcounts.value)'))
    ->groupBy('albums.id')
    ->get();

当然,你可以走另一条路,但这很简单。我不确定您是否会因为 1 到多个曲目 -> 专辑关系而受到欺骗,但 groupBy 会解决这个问题。

【讨论】:

非常感谢巴拉德,这是我之前尝试过的方向之一(告诉你,已经为此发疯了一段时间 :-))这里的问题是它只需要playcounts 表中的第一个条目 - 同样,如果已经有一个更新的条目。问题在于识别最新的播放次数 我已经重建了您的数据结构并自己运行了该查询,我得到了多张专辑,其中包含该专辑中每首曲目的播放次数的总和 也很有可能您在问题中打错字了,实际上您想要的记录少于或少于 24 小时前,如果是这种情况,where('created_at', '&lt;=', Carbon::now()-&gt;subDay()) 变为 where('created_at', '&gt;=', Carbon::now()-&gt;subDay())跨度> 另外,将playcounts.value 替换为您存储计数的字段名称 你好 Ballard,不,我确定它需要超过 24 小时 :-) 查看我的 playcounts 表假设我有 2 个条目,用于 1 个轨道 ID track_id playcount created_at 1 1 100 2020- 10-16 14:28:11 2 1 200 2020-10-17 14:28:11 我怎样才能只选择 id=2 (因为 created_at 比另一个新)然后检查 created_at 是否超过 24 小时?

以上是关于Laravel HasMany 查询最新入口并返回相关模型的主要内容,如果未能解决你的问题,请参考以下文章

Laravel hasMany 是返回无结果

在 Laravel 中通过 ajax 加载更雄辩的 hasMany 关系查询?

是否可以从 Laravel 中的 hasmany 关系中返回特定的索引元素?

Laravel hasMany 到复合表返回空数组

我的模型Laravel如何能够在hasMany中返回每个项目的所有价格?

laravel关联查询,同时返回关联表和被关联表的信息,怎么做