Laravel查询构建器中将列值转为数组并使用whereIn的实现
解决Laravel中逗号分隔字段的包含查询问题
你原来的whereIn用法逻辑完全错误,而且针对逗号分隔的字符串字段,whereIn并不适用——它是用来匹配字段值在给定数组中的情况,和你要找“字段包含某个值”的需求刚好相反。
针对这种存储逗号分隔ID的场景,最靠谱的方式是用MySQL的FIND_IN_SET函数,结合Laravel的查询构建器实现:
方案一:使用whereRaw直接调用函数
$customerId = $request->input('customer_id'); $to_email = Permission::where('price_list', $request->input('price_list')) ->where('level_one', '1') // 用FIND_IN_SET在逗号分隔的字符串中精准查找指定ID ->whereRaw("FIND_IN_SET(?, permissions.customer_id)", [$customerId]) ->join('users', 'users.id', '=', 'permissions.user_id') ->select('users.fname', 'users.lname', 'users.email') ->first();
FIND_IN_SET会精准匹配逗号分隔的单个值,避免用like查询时出现“查2却匹配到12”这类错误。
方案二:结合DB::raw使用where
如果你习惯用Laravel的DB门面写法,也可以这么实现:
use Illuminate\Support\Facades\DB; $customerId = $request->input('customer_id'); $to_email = Permission::where('price_list', $request->input('price_list')) ->where('level_one', '1') ->where(DB::raw("FIND_IN_SET(?, permissions.customer_id)", [$customerId])) ->join('users', 'users.id', '=', 'permissions.user_id') ->select('users.fname', 'users.lname', 'users.email') ->first();
额外建议
虽然上面的方法能解决当前问题,但从数据库设计的角度来说,逗号分隔存储关联ID是反范式的做法,会导致查询效率低、难以维护。如果项目允许,建议重构数据库:
- 创建一个中间表(比如
permission_customer),包含permission_id和customer_id两个字段 - 删除原
permissions表中的customer_id字段 - 之后用多对多关联查询,不仅更规范,查询性能也会更好
内容的提问来源于stack exchange,提问作者Mannu254
相关产品推荐
相关产品推荐

