Laravel 8:如何基于WHERE子句切换关联并复用查询数据实现条件逻辑
Laravel 8 查询场景解决方案
一、基于WHERE条件切换关联关系
假设你有一个User模型,默认关联primary_address,但当用户的is_secondary字段为true时,需要改用secondary_address关联。可以通过以下两种方式实现:
方式1:使用when方法动态加载关联
通过条件判断决定加载哪个关联,直接跳过不需要的关联:
$users = User::query() ->where('status', 'active') ->when($yourCondition, function ($query) { // 满足条件时加载secondary_address,跳过primary_address $query->with('secondary_address'); }, function ($query) { // 不满足条件时加载默认的primary_address $query->with('primary_address'); }) ->get();
方式2:关联查询中通过WHERE条件筛选关联表
如果需要在关联的WHERE逻辑里根据主表字段切换关联表,比如主表User的type为1时关联GroupA,否则关联GroupB:
$users = User::query() ->where(function ($query) { $query->where('type', 1) ->whereExists(function ($sub) { $sub->select(DB::raw(1)) ->from('group_a') ->whereColumn('group_a.user_id', 'users.id'); }) ->orWhere('type', '!=', 1) ->whereExists(function ($sub) { $sub->select(DB::raw(1)) ->from('group_b') ->whereColumn('group_b.user_id', 'users.id'); }); }) ->get();
二、在WHERE子句中用当前数据实现IF ELSE逻辑
可以通过case表达式或whereRaw实现基于当前查询字段的条件逻辑:
方式1:使用case表达式筛选结果
比如筛选出score >=90时等级为'A'、score >=80时等级为'B'的用户:
$users = User::query() ->select('*') ->whereRaw(" CASE WHEN score >= 90 THEN 'A' WHEN score >= 80 THEN 'B' ELSE 'C' END IN ('A', 'B') ") ->get();
方式2:基于字段值动态添加WHERE条件
比如根据用户age字段值,成年用户筛选is_adult = true,未成年用户筛选is_minor = true:
$users = User::query() ->where(function ($query) { $query->whereExists(function ($sub) { $sub->select(DB::raw(1)) ->from('users as u') ->whereColumn('u.id', 'users.id') ->where('u.age', '>=', 18) ->where('u.is_adult', true); }) ->orWhereExists(function ($sub) { $sub->select(DB::raw(1)) ->from('users as u') ->whereColumn('u.id', 'users.id') ->where('u.age', '<', 18) ->where('u.is_minor', true); }); }) ->get();
方式3:简单分支条件筛选
直接通过orWhere组合不同字段值的筛选逻辑:
$users = User::query() ->where(function ($query) { $query->where('status', 'active') ->where('last_login', '>=', now()->subMonth()) ->orWhere('status', 'inactive') ->where('last_login', '<=', now()->subYear()); }) ->get();
内容的提问来源于stack exchange,提问作者Syed Jalal
相关产品推荐
相关产品推荐

