Laravel/Eloquent中如何实现多字段组合的whereIn查询?
解决Eloquent中多字段组合WHERE IN的查询问题
最近我碰到了一个数据库查询的需求,折腾了好一会儿才找到合适的Eloquent实现方式,分享给大家:
背景与需求
我有三张数据库表:
- 两张普通业务表,均包含ID及其他业务字段
- 一张关联分配表(命名为
table_3),结构为ID、table1_id、table2_id和text字段
我需要查询table_3中匹配多组table1_id和table2_id组合的数据,对应的原生SQL是这样的:
SELECT * FROM table_3 where (table1_id, table2_id) in ( (1, 1), (2, 1), (3, 3));
前端通过API提交的请求体格式如下:
{ "assignments": [ {"table1_id": 1, "table2_id": 1}, {"table1_id": 2, "table2_id": 1}, {"table1_id": 3, "table2_id": 3} ] }
同时我用Laravel的验证规则对请求做了校验:
->validate($request, [ 'assignments' => 'required|array', 'assignments.*.table1_id' => 'required|integer|min:1|max:20', 'assignments.*.table2_id' => 'required|integer|min:1|max:20' ])
遇到的问题
一开始我纠结怎么用Eloquent的whereIn方法实现这种多字段组合匹配的查询,普通的whereIn只能处理单个字段的IN条件,没法直接支持这种多字段的情况。
解决方案
后来我参考了社区的解决方案并做了适配,最终实现的Eloquent查询代码如下:
// 先将请求中的assignments转换为二维数组格式 $combinations = collect($request->input('assignments')) ->map(fn($item) => [$item['table1_id'], $item['table2_id']]) ->toArray(); // 构建多字段IN查询 $results = Table3::whereRaw( '(table1_id, table2_id) IN (?)', [implode(',', array_map(fn($comb) => "({$comb[0]}, {$comb[1]})", $combinations))] )->get();
这个方案本质上是利用whereRaw来拼接原生SQL的多字段IN条件,同时通过集合处理把请求里的对象数组转换成需要的组合格式,测试下来和原生SQL的执行效果完全一致,完美满足需求。
内容的提问来源于stack exchange,提问作者Benguino
相关产品推荐
相关产品推荐

