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

Laravel 8如何两表关联无重复查询,获取客户对应最新地址

Laravel查询构造器实现客户关联单条最新地址方案

场景说明

  • 存在两张数据表:Customer(客户表)、Address(地址表)
  • 两表为一对多关联关系:单个客户可拥有多条地址记录
  • 需求:使用Laravel查询构造器做关联查询,返回客户列表时每个客户仅匹配最新的一条地址记录,无重复结果
  • 示例表结构与测试数据:
ADDRESS TABLE
id : 1
city:"cebu"
zip_code:"600"
cus_id:1

id:2
city:"mandaue"
zip_code:"6001"
cus_id:1

CUSTOMER TABLE
id: 1
name:"JOHN DOE"
  • 预期结果:返回客户「JOHN DOE」及其关联ID为2的最新地址记录

实现逻辑

核心思路是先通过子查询锁定每个客户对应的最新地址ID(地址表自增主键id越大,代表记录越新),再通过关联子查询结果匹配地址详情,从根源避免普通join分组带来的字段不匹配、SQL_MODE报错、结果重复问题。

可直接复用的代码

<?php
// 第一步:构建子查询,按客户ID分组取出每个客户最新的地址ID
$latestAddress = DB::table('address')
    ->select('cus_id', DB::raw('MAX(id) as latest_address_id'))
    ->groupBy('cus_id');

// 第二步:关联客户表、子查询、地址表拿到最终结果
$customerList = DB::table('customer as c')
    // 关联最新地址子查询
    ->leftJoinSub($latestAddress, 'addr_map', function ($join) {
        $join->on('c.id', '=', 'addr_map.cus_id');
    })
    // 关联地址表拿完整地址信息
    ->leftJoin('address as a', function ($join) {
        $join->on('a.id', '=', 'addr_map.latest_address_id');
    })
    // 按需选择要返回的字段
    ->select(
        'c.id as customer_id',
        'c.name',
        'a.id as address_id',
        'a.city',
        'a.zip_code'
    )
    ->get();

结果验证

针对给出的测试数据,子查询会先取出cus_id=1对应的最新地址ID为2,最终关联查询返回的结果就是JOHN DOE匹配ID为2、city为mandaue、zip_code为6001的地址记录,完全符合预期,且不会出现客户重复返回的问题。

注意:如果地址表的新旧判断逻辑不是按自增ID,而是按创建时间字段(比如created_at),只需要把子查询里的MAX(id)替换为对应时间字段的最大值,同时调整后续关联条件匹配即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:51:20