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

如何基于center_id与service_id获取CenterService表的最新唯一记录?

解决CenterService去重并保留最新记录的问题

嘿,我明白你的问题了!你当前的代码只是把符合条件的记录按时间倒序排列,但并没有真正去除重复的center_id和service_id组合——同一个组合的所有历史记录都会被返回,只是最新的排在最前面而已。要实现每个(center_id, service_id)组合只保留最新一条记录的需求,我们需要先找到每个组合的最新记录标识,再基于这个标识查询完整数据。

下面给你两种实用的解决方案:

方案一:利用自增ID(如果ID是递增的)

如果你的center_services表有自增主键id,且最新创建的记录ID最大,这种方法最简洁高效:

// 先获取需要的服务ID数组
$requiredServices = Service::whereRequiredService(true)->pluck('id');

// 找出每个(center_id, service_id)组合的最新记录ID
$latestRecordIds = CenterService::select(DB::raw('MAX(id) as id'))
    ->whereIn('service_id', $requiredServices)
    ->groupBy('center_id', 'service_id')
    ->pluck('id');

// 根据最新ID集合获取完整的去重记录
$uniqueLatestCenterServices = CenterService::whereIn('id', $latestRecordIds)->get();

方案二:利用时间字段(比如created_at/updated_at)

如果你的表依赖时间字段判断“最新”(比如允许ID不连续或有更新场景),可以用时间字段来定位最新记录:

$requiredServices = Service::whereRequiredService(true)->pluck('id');

// 子查询:获取每个组合的最新时间戳
$latestTimeSubquery = CenterService::select(
    'center_id', 
    'service_id', 
    DB::raw('MAX(created_at) as latest_created') // 换成你的时间字段,比如updated_at
)
->whereIn('service_id', $requiredServices)
->groupBy('center_id', 'service_id');

// 关联子查询,匹配出完整的最新记录
$uniqueLatestCenterServices = CenterService::joinSub(
    $latestTimeSubquery,
    'latest_records',
    function ($join) {
        $join->on('center_services.center_id', '=', 'latest_records.center_id')
             ->on('center_services.service_id', '=', 'latest_records.service_id')
             ->on('center_services.created_at', '=', 'latest_records.latest_created'); // 对应上面的时间字段
    }
)->get();

关键原理说明

  • groupBy('center_id', 'service_id') 会把相同center_id+service_id的记录归为一组
  • 通过MAX(id)或MAX(created_at)拿到每组的“最新”标识
  • 最后基于这个标识查询,就能保证每个组合只返回一条最新记录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:57:41