Php Laravel如何实现除type=2外其余类型仅返回唯一值的查询
需求实现方案
你可以通过以下两种方式实现需求,根据你的数据量规模选择即可:
方案1:集合处理(适合单MIT_ID下数据量小于1000的场景)
先全量拉取符合条件的排序后数据,再通过遍历过滤出符合规则的结果:
// 先按规则拉取全量符合MIT_ID条件、且按updated_at降序的数据 $entries = User::orderBy('updated_at', 'DESC') ->where('MIT_ID', $MIT_ID) ->get(); $typeCount = []; $result = collect(); foreach ($entries as $entry) { $type = $entry->type; // 非type=2的只留1条 if ($type != 2) { if (!isset($typeCount[$type])) { $result->push($entry); $typeCount[$type] = 1; } } else { // type=2的最多留2条 if (!isset($typeCount[$type]) || $typeCount[$type] < 2) { $result->push($entry); $typeCount[$type] = isset($typeCount[$type]) ? $typeCount[$type] + 1 : 1; } } } // $result即为最终符合要求的结果
你之前的写法仅调用unique('type_id')会让所有type仅保留1条,不符合type=2最多留2条的要求,同时注意你表中的字段是type不是type_id,存在字段名写错的问题。
方案2:SQL层面union查询(适合大数据量场景,性能更高)
直接在查询层拆分查询逻辑,合并结果后再排序:
// 查type=2的最新2条 $type2Query = User::where('MIT_ID', $MIT_ID) ->where('type', 2) ->orderBy('updated_at', 'DESC') ->limit(2); // 查其他type的最新1条 $otherTypeQuery = User::where('MIT_ID', $MIT_ID) ->where('type', '!=', 2) ->orderBy('updated_at', 'DESC') ->groupBy('type'); // 合并两个查询结果后整体按updated_at降序排序 $result = $type2Query->union($otherTypeQuery) ->orderBy('updated_at', 'DESC') ->get();
如果你的数据库开启了严格模式,group by时需要注意配置允许非聚合字段查询,或者调整查询逻辑用子查询取每个type的最新id关联查询即可。
内容的提问来源于stack exchange,提问作者Joha
相关产品推荐
相关产品推荐

