Laravel多条件按信息完善度排序,如何关联about模型与评论数
解决方案
因为with()预加载不会将关联表字段加入主查询,所以无法直接在orderByRaw中读取about关联的字段值,需要先通过左连接将user_abouts表关联到主查询中,以下是两种可行实现:
方案1:基于多层CASE的优先级排序(适配你现有写法)
$users = User::where('users.status', 1) ->select('users.*') // 避免关联表和主表同名字段冲突 ->withCount('reviews') ->with('reviews', 'about') // 左连about表获取简介字段 ->leftJoin('user_abouts', 'users.id', '=', 'user_abouts.user_id') // 第一优先级:按完善度从高到低排序 ->orderByRaw(" CASE WHEN is_native != '0' AND photo != '' AND user_abouts.about IS NOT NULL AND TRIM(user_abouts.about) != '' THEN 0 WHEN is_native != '0' AND photo != '' THEN 1 WHEN user_abouts.about IS NOT NULL AND TRIM(user_abouts.about) != '' THEN 2 ELSE 3 END ASC ") // 第二优先级:同完善度下评论数越多越靠前 ->orderBy('reviews_count', 'DESC') ->paginate(10);
排序规则说明:
- 同时满足「is_native非0、头像非空、简介非空」的用户排最前
- 其次是满足「is_native非0、头像非空」的用户
- 再次是仅「简介非空」的用户
- 同完善度的用户按评论数倒序排列
方案2:权重打分制(更灵活的可扩展方案)
如果后续需要调整各完善维度的优先级,用权重累加的方式更易维护:
$users = User::where('users.status', 1) ->select('users.*') ->withCount('reviews') ->with('reviews', 'about') ->leftJoin('user_abouts', 'users.id', '=', 'user_abouts.user_id') // 按完善度总得分倒序,得分越高排名越靠前 ->orderByRaw(" ( (CASE WHEN is_native != '0' THEN 1 ELSE 0 END) * 3 + (CASE WHEN photo != '' THEN 1 ELSE 0 END) * 2 + (CASE WHEN user_abouts.about IS NOT NULL AND TRIM(user_abouts.about) != '' THEN 1 ELSE 0 END) * 4 + reviews_count * 1 ) DESC ") ->paginate(10);
规则说明:
给每个完善维度分配自定义权重,数值越高代表该维度优先级越高,你可以根据业务需求自由调整各维度的权重值:
- 示例中
about简介权重最高为4,is_native权重3,头像权重2,评论数每多1条加1分 - 最终按总得分倒序排列,得分越高排名越靠前
注意事项
- 必须加
select('users.*')避免关联表与主表同名字段覆盖 - 用
leftJoin保证没有填写简介的用户不会被过滤掉 - 若
user_abouts表中about字段可能存在空白内容,TRIM()判断可以避免空白内容被判定为已填写
内容的提问来源于stack exchange,提问作者Khirad Zahra
相关产品推荐
相关产品推荐

