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
相关产品推荐
相关产品推荐

