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

基于单字段去重且保留首次行的所有表列查询最简方法

单字段去重保留首行全列查询方案

首先明确前提:SQL不存在内置的行先后顺序,你需要提前指定一个可唯一确定行出现顺序的字段(如自增主键、数据插入时间戳等),才能准确定位“首次出现”的行。

以下是不同场景下的实现方案:

通用方案(支持所有支持窗口函数的数据库,如MySQL 8.0+、PostgreSQL、SQL Server、Spark SQL等)

核心逻辑是用ROW_NUMBER()窗口函数对目标去重字段分组,按行顺序字段排序后取每组的第一行:

-- 把Col_A替换为你要去重的字段,create_time替换为你用来判断行先后的排序字段,你的表名替换为实际表名
WITH ranked_data AS (
    SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY Col_A ORDER BY create_time ASC) AS row_rank
    FROM 你的表名
)
-- 支持EXCEPT语法的数据库可以直接排除行号列,不需要手动写所有列名
SELECT * EXCEPT(row_rank)
FROM ranked_data
WHERE row_rank = 1;

如果你的数据库不支持EXCEPT语法,又不想手动写100多个列名,可以用系统表快速生成需要查询的列名:

  • MySQL查询:SELECT GROUP_CONCAT(COLUMN_NAME SEPARATOR ', ') FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '你的表名';
  • PostgreSQL查询:SELECT string_agg(column_name, ', ') FROM information_schema.columns WHERE table_name = '你的表名';
    把查询得到的列名字符串替换上面SQL的* EXCEPT(row_rank)部分即可。

低版本MySQL(5.x及以下,不支持窗口函数)方案

可以用分组取首次出现的标识值再关联原表的方式实现:

SELECT t1.*
FROM 你的表名 t1
INNER JOIN (
    -- 取每个Col_A对应的最小排序字段值,即首次出现的行的标识
    SELECT Col_A, MIN(create_time) AS first_create_time
    FROM 你的表名
    GROUP BY Col_A
) t2 ON t1.Col_A = t2.Col_A AND t1.create_time = t2.first_create_time;

提示:如果同一个Col_A下存在多个相同create_time的行,可以把排序字段换成自增主键,避免返回重复行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 11:39:03