You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Eloquent hasMany关联中orderBy与take共同使用无返回结果问题

问题根因
  • 你遇到的问题本质是Laravel Eloquent关联定义中直接使用take()的作用范围不符合预期:take()是作用在关联查询的全局结果集上,而非为每个父模型单独限制关联条目数。
  • 单独使用orderBy时没有结果条数限制,所有匹配外键的关联数据都会被返回,所以表现正常;单独使用take时你大概率只查询了单个父模型,全局limit返回的刚好是该父模型对应的关联数据,因此也符合预期。
  • 二者同时使用时,如果你是通过with预加载多个父模型的关联数据,最终生成的SQL会是SELECT * FROM manual_ticket_log WHERE manual_ticket_id IN (?,?,?) ORDER BY id DESC LIMIT 1,这条SQL只会返回所有父模型中匹配到的第一条关联数据,其余父模型的关联结果都会是空数组,和你遇到的表现一致。
解决方案

不要直接在hasMany关联定义中添加take限制,根据使用场景选择对应写法:

  1. 仅查询单个父模型的场景
    先定义无take限制的基础关联:
public function manual_ticket_log(){
    return $this->hasMany('App\ManualTicketLog','manual_ticket_id','id')->orderBy('id','desc');
}

查询时主动加条数限制即可:

// 懒加载写法
$ticket = ManualTicket::find($id);
$latestLog = $ticket->manual_ticket_log()->take(1)->get();

// 预加载写法
$ticket = ManualTicket::with(['manual_ticket_log' => function($q) {
    $q->take(1);
}])->find($id);
  1. 批量查询多个父模型,每个父模型都需要返回1条最新关联记录的场景
    使用子查询实现按父模型单独限制条数:
$tickets = ManualTicket::select('*')
    ->addSelect(['latest_log_id' => ManualTicketLog::select('id')
        ->whereColumn('manual_ticket_id', 'manual_tickets.id')
        ->orderBy('id', 'desc')
        ->take(1)
    ])
    ->with('manual_ticket_log')
    ->get();

内容的提问来源于stack exchange,提问作者Yeo Bryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 14:15:04