You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL结果去重:单列值重复时仅保留一行(SQL/Rails方案)

如何在MySQL和Rails中对指定列去重并保留唯一行?

我之前处理过类似的去重需求,给你整理了两种实用方案,分别对应原生MySQL和Rails ActiveRecord的实现,刚好匹配你的需求:

方案一:原生MySQL实现

方法1:GROUP BY + 关联查询(适合指定保留行规则的场景)

如果想保留每个addr分组中id最小的那一行(和你示例的预期结果一致),可以先通过分组找到每个addr对应的最小id,再关联原表获取完整行数据:

SELECT t.id, t.name, t.addr, t.add_id
FROM (
    SELECT addr, MIN(id) AS min_id
    FROM your_table_name -- 替换成你的实际表名
    GROUP BY addr
) AS sub
JOIN your_table_name t ON t.id = sub.min_id;

如果想保留id最大的行,只需把MIN(id)改成MAX(id)即可。

方法2:窗口函数(更灵活的排序规则)

MySQL 8.0及以上版本支持窗口函数,这种方法可以自定义分组内的排序规则,比如按id升序取第一行:

SELECT id, name, addr, add_id
FROM (
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY addr ORDER BY id ASC) AS row_num
    FROM your_table_name -- 替换成你的实际表名
) AS sub
WHERE sub.row_num = 1;

如果需要调整保留的行,修改ORDER BY后的字段即可(比如按add_id降序排序)。

方案二:Rails ActiveRecord实现

方法1:对应GROUP BY关联查询的写法

假设你的模型名为YourModel(表名默认是your_models),可以用ActiveRecord拼接子查询:

# 先获取每个addr对应的最小id
subquery = YourModel.select(:addr, 'MIN(id) AS min_id').group(:addr)
# 关联原表获取完整数据
unique_records = YourModel.joins("JOIN (#{subquery.to_sql}) AS sub ON your_models.id = sub.min_id")
                          .select('your_models.id, your_models.name, your_models.addr, your_models.add_id')

方法2:窗口函数的ActiveRecord写法

同样利用子查询实现窗口函数逻辑:

# 给每条数据添加分组内的行号
subquery = YourModel.select('*, ROW_NUMBER() OVER (PARTITION BY addr ORDER BY id ASC) AS row_num')
# 筛选出每组的第一行
unique_records = YourModel.from("(#{subquery.to_sql}) AS sub")
                          .where('sub.row_num = 1')
                          .select('sub.id, sub.name, sub.addr, sub.add_id')

说明:如果是使用PostgreSQL的Rails项目,还可以用distinct_on语法更简洁,但MySQL不支持该特性,所以上面的两种方法更通用。

内容的提问来源于stack exchange,提问作者ZZzzZZzz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 11:32:31