如何仅在左关联属性分组表存在时添加状态与类型查询条件?
Laravel查询优化:属性分组不存在时的条件兼容处理
原始查询代码
DB::table('attribute_model_values')->select([ 'attribute_model_values.value', 'attribute_model_values.model_id as p_id', 'attribute_values.title as v_title', 'attribute_attributes.id as a_id', 'attribute_attributes.title as a_title', 'attribute_attributes.field_type as a_type', 'attribute_attribute_groups.id as ag_id', 'attribute_attribute_groups.title as g_title', ]) ->leftJoin('attribute_values', 'attribute_model_values.value_id', '=', 'attribute_values.id') ->leftJoin('attribute_attributes', 'attribute_values.attribute_id', '=', 'attribute_attributes.id') ->leftJoin('attribute_attribute_group_attribute', 'attribute_attribute_group_attribute.attribute_id', '=', 'attribute_attributes.id') ->leftJoin('attribute_attributes_categories as ac', 'ac.attribute_id', '=', 'attribute_attributes.id') ->leftJoin('attribute_attribute_groups', 'attribute_attribute_group_attribute.attribute_group_id', '=', 'attribute_attribute_groups.id') ->leftJoin('attribute_attribute_groups_categories as agc', 'agc.attribute_group_id', '=', 'attribute_attribute_groups.id') ->where(function ($query) { $query ->where('attribute_model_values.model_id', '=', $this->id) ->where('attribute_model_values.model_type', '=', (new Product())->getMorphClass()); }) ->where('attribute_attribute_group_attribute.status', '=', Status::ACTIVE) ->where('attribute_attribute_groups.type', '=', $type) ->where('attribute_attributes.type', '=', $type) ->where(function ($query) { $query ->where('agc.category_id', '=', $this->getMainCategory()->id) ->orWhere('ac.category_id', '=', $this->getMainCategory()->id); })->orderBy('attribute_attribute_group_attribute.priority')->get();
问题说明
当前查询使用左连接关联属性分组相关表,但后续直接添加了两个强制条件,导致当属性分组不存在时(关联表字段为null),整个查询无法返回任何结果:
->where('attribute_attribute_group_attribute.status', '=', Status::ACTIVE) ->where('attribute_attribute_groups.type', '=', $type)
需要实现:仅当属性分组实际存在时,才检查上述状态与类型条件;若属性分组不存在,仍能返回其他符合条件的数据。
解决方案
将上述两个强制条件替换为条件判断闭包,通过判断关联表主键是否存在来决定是否应用条件:
修改后的完整查询代码
DB::table('attribute_model_values')->select([ 'attribute_model_values.value', 'attribute_model_values.model_id as p_id', 'attribute_values.title as v_title', 'attribute_attributes.id as a_id', 'attribute_attributes.title as a_title', 'attribute_attributes.field_type as a_type', 'attribute_attribute_groups.id as ag_id', 'attribute_attribute_groups.title as g_title', ]) ->leftJoin('attribute_values', 'attribute_model_values.value_id', '=', 'attribute_values.id') ->leftJoin('attribute_attributes', 'attribute_values.attribute_id', '=', 'attribute_attributes.id') ->leftJoin('attribute_attribute_group_attribute', 'attribute_attribute_group_attribute.attribute_id', '=', 'attribute_attributes.id') ->leftJoin('attribute_attributes_categories as ac', 'ac.attribute_id', '=', 'attribute_attributes.id') ->leftJoin('attribute_attribute_groups', 'attribute_attribute_group_attribute.attribute_group_id', '=', 'attribute_attribute_groups.id') ->leftJoin('attribute_attribute_groups_categories as agc', 'agc.attribute_group_id', '=', 'attribute_attribute_groups.id') ->where(function ($query) { $query ->where('attribute_model_values.model_id', '=', $this->id) ->where('attribute_model_values.model_type', '=', (new Product())->getMorphClass()); }) // 替换后的条件判断逻辑 ->where(function ($query) use ($type) { // 允许属性分组不存在的情况(关联表主键为null) $query->whereNull('attribute_attribute_group_attribute.id') // 若属性分组存在,则必须满足状态和类型要求 ->orWhere(function ($subQuery) use ($type) { $subQuery->where('attribute_attribute_group_attribute.status', '=', Status::ACTIVE) ->where('attribute_attribute_groups.type', '=', $type); }); }) ->where('attribute_attributes.type', '=', $type) ->where(function ($query) { $query ->where('agc.category_id', '=', $this->getMainCategory()->id) ->orWhere('ac.category_id', '=', $this->getMainCategory()->id); })->orderBy('attribute_attribute_group_attribute.priority')->get();
逻辑说明
- 左连接场景下,属性分组不存在时
attribute_attribute_group_attribute.id会为null,whereNull允许这类数据通过 - 当属性分组存在(
id不为null)时,进入orWhere闭包,强制检查状态和类型条件,保证数据合法性
内容的提问来源于stack exchange,提问作者arya_la
相关产品推荐
相关产品推荐

