Rails查询Location表排除指定id且按ip_address去重保留首条的实现
Location模型去重查询实现方案
实现逻辑
- 第一步:过滤排除id=1的记录
- 第二步:对剩余记录按
ip_address字段分组,取每个分组下最小的id,即为重复ip下要保留的唯一记录 - 第三步:根据筛选出的id集合查询完整记录即可
代码实现(以Laravel Eloquent为例)
直接替换原有find_all_non_duplicate方法逻辑即可:
public function find_all_non_duplicate() { // 筛选符合要求的记录id:排除id=1,每个ip_address保留最小id的记录 $keepIds = self::where('id', '<>', 1) ->selectRaw('MIN(id) as id') ->groupBy('ip_address') ->pluck('id'); // 返回完整的记录集合,按id升序排序 return self::whereIn('id', $keepIds) ->orderBy('id') ->get(); }
对应原生SQL查询
SELECT * FROM locations WHERE id IN ( SELECT MIN(id) FROM locations WHERE id != 1 GROUP BY ip_address ) ORDER BY id;
注意事项
- 该写法兼容开启
ONLY_FULL_GROUP_BYSQL模式的数据库环境,不会触发分组语法错误 - 数据量较大时可以给
ip_address和id字段加联合索引提升查询性能
内容的提问来源于stack exchange,提问作者current_user
相关产品推荐
相关产品推荐

