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

如何用groupBy和orderBy获取两表关联的最新插入数据

问题分析与解决方案

你的问题出在groupBy的使用逻辑上:当你按remcal.invoice_id分组后,虽然通过MAX(remcal.id)拿到了每组最大的记录ID,但select里的remcal.*、inv.*并不会自动关联到这个最大ID对应的那条记录——数据库会从同组的记录里随机选取一条返回,所以自然拿不到最新插入的数据。

下面提供两种可行的解决方案:

方案一:子查询预取最新记录ID

先通过子查询找出每个invoice_id对应的最新reminders_calendar记录ID,再关联原表获取完整数据:

$def_reminders = Invoice::from('invoices AS inv')
    ->join(
        DB::raw('(SELECT invoice_id, MAX(id) AS max_remcal_id FROM reminders_calendar WHERE date_when = "2024-01-03" AND reminder_type IN ("InProgress", "Waiting") GROUP BY invoice_id) AS latest_rem'),
        'latest_rem.invoice_id', '=', 'inv.id'
    )
    ->join('reminders_calendar AS remcal', 'remcal.id', '=', 'latest_rem.max_remcal_id')
    ->where([
        'inv.user_id' => 1,
        'inv.is_deleted' => '0',
    ])
    ->where('inv.reminder_status', '!=', 'Enabled')
    ->select('remcal.*', 'inv.*')
    ->orderBy('remcal.id', 'desc')
    ->get();

方案二:窗口函数(MySQL 8.0+适用)

利用窗口函数ROW_NUMBER()给每个invoice_id的记录按ID倒序排号,直接取每组的第一条最新记录:

$def_reminders = Invoice::from('invoices AS inv')
    ->join(
        DB::raw('(SELECT *, ROW_NUMBER() OVER (PARTITION BY invoice_id ORDER BY id DESC) AS rn FROM reminders_calendar WHERE date_when = "2024-01-03" AND reminder_type IN ("InProgress", "Waiting")) AS remcal'),
        'remcal.invoice_id', '=', 'inv.id'
    )
    ->where([
        'inv.user_id' => 1,
        'inv.is_deleted' => '0',
        'remcal.rn' => 1
    ])
    ->where('inv.reminder_status', '!=', 'Enabled')
    ->select('remcal.*', 'inv.*')
    ->orderBy('remcal.id', 'desc')
    ->get();

说明

  • 方案一兼容所有MySQL版本,适合老项目;
  • 方案二代码更简洁,逻辑清晰,但要求MySQL版本在8.0及以上。

内容的提问来源于stack exchange,提问作者Mano Mahe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 22:46:04