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

SQL面试题:除SELECT DISTINCT外,如何获取表中唯一行?

几种SQL去重获取唯一行的替代方法(替代DISTINCT)

针对你面试遇到的这个SQL去重问题,除了SELECT DISTINCT * FROM TableName;,还有以下几种常用的实现方法:

1. 使用GROUP BY分组

通过将所有需要去重的列作为分组依据,每个分组仅返回一行,实现去重效果:

SELECT Name, id, orderNo
FROM TableName
GROUP BY Name, id, orderNo;

这种方式和DISTINCT的底层逻辑类似,但如果后续需要对分组数据做聚合计算(比如统计重复次数),GROUP BY会更灵活。

2. 使用窗口函数ROW_NUMBER()

通过给重复分组内的行编号,筛选出每组的第一行来实现去重:

WITH RankedRows AS (
    SELECT 
        Name, id, orderNo,
        -- 按需要去重的列分组,给每组内的行编号
        ROW_NUMBER() OVER (PARTITION BY Name, id, orderNo ORDER BY (SELECT NULL)) AS rn
    FROM TableName
)
SELECT Name, id, orderNo
FROM RankedRows
WHERE rn = 1;

这里ORDER BY (SELECT NULL)是为了在不需要特定排序逻辑时兼容多数数据库,你也可以根据实际需求替换为具体列(比如如果有时间列,按时间排序保留最新行)。

3. 使用EXISTS子查询结合行标识符

通过判断当前行是否是分组中的“首行”来保留唯一记录,需要用到数据库自带的行唯一标识符(不同数据库写法不同):

-- PostgreSQL示例,用ctid作为行标识符
SELECT t1.Name, t1.id, t1.orderNo
FROM TableName t1
WHERE NOT EXISTS (
    SELECT 1
    FROM TableName t2
    WHERE t2.Name = t1.Name 
      AND t2.id = t1.id 
      AND t2.orderNo = t1.orderNo
      AND t2.ctid < t1.ctid
);

-- MySQL示例,如果表有主键primary_id(注意这里指表的主键,不是数据里的id列)
SELECT t1.Name, t1.id, t1.orderNo
FROM TableName t1
WHERE NOT EXISTS (
    SELECT 1
    FROM TableName t2
    WHERE t2.Name = t1.Name 
      AND t2.id = t1.id 
      AND t2.orderNo = t1.orderNo
      AND t2.primary_id < t1.primary_id
);

这种方法适合需要精确控制保留哪一行的场景,比如保留最早插入的记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 05:54:22