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

SQL实现单字段去重并取同组另一字段首条记录的查询方法

问题场景

现有包含id1、id2、other三个字段的数据表,样例数据如下:

id1id2other
1ap
1bq
2cq
2dq
2eq

需求为实现类似SELECT DISTINCT id1的去重效果,按id1分组后仅保留每个分组下第一次出现的id2取值,过滤其余冗余记录,期望输出结果如下:

id1id2
1a
2c
实现方法

首先需要明确:SQL中的表是无序集合,不存在天然的"先后顺序",要准确定义"第一次出现"的记录,必须有可标识记录插入/排列顺序的字段(比如自增主键、创建时间字段,下文示例中用seq代指该类字段,值越小代表记录出现越早)。

通用写法(支持所有现代数据库)

所有支持SQL:2003标准窗口函数的数据库(MySQL 8.0+、PostgreSQL、SQL Server、Oracle等),可以用ROW_NUMBER()窗口函数实现,逻辑清晰且性能稳定:

SELECT id1, id2
FROM (
    SELECT
        id1,
        id2,
        ROW_NUMBER() OVER (PARTITION BY id1 ORDER BY seq ASC) AS row_rank
    FROM 你的表名
) tmp
WHERE row_rank = 1;

老版本兼容写法(MySQL 5.x等不支持窗口函数的环境)

可以用NOT EXISTS子查询关联实现,效果和窗口函数一致:

SELECT t1.id1, t1.id2
FROM 你的表名 t1
WHERE NOT EXISTS (
    SELECT 1
    FROM 你的表名 t2
    WHERE t2.id1 = t1.id1
      AND t2.seq < t1.seq
);

特殊场景简化写法

如果你的业务场景中,每个id1分组下需要保留的id2刚好是该分组内最小的取值(和本次样例数据特征匹配),也可以直接用聚合函数简化,但该写法不具备通用性,仅当排序规则和id2本身的排序规则一致时可使用:

SELECT id1, MIN(id2) AS id2
FROM 你的表名
GROUP BY id1;

注意:如果没有明确的排序字段就直接写分组取首行的逻辑,数据库返回的id2取值是不确定的,可能随执行计划、数据量变化发生改变,无法稳定得到预期结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:45:51