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

SQL去重需求:指定列重复时保留首行并返回全列

解决方案

MySQL/MariaDB 实现方式

用ROW_NUMBER()窗口函数按指定列分组,给每组的行编号,只取每组第一行。如果不需要特定排序逻辑,用(SELECT 1)让数据库返回任意首行即可:

SELECT *
FROM (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY DeviceId, TransactionId, IndetId, Datetime, SalesId 
                              ORDER BY (SELECT 1)) AS row_num
    FROM Foo
) AS temp
WHERE row_num = 1;

要是需要按特定规则选首行(比如最新时间、最大Quantity),把(SELECT 1)换成对应列就行,比如ORDER BY Datetime DESC。

SQL Server 实现方式

逻辑和MySQL一致,用CTE加窗口函数:

WITH RankedRows AS (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY DeviceId, TransactionId, IndetId, Datetime, SalesId 
                              ORDER BY (SELECT NULL)) AS row_num
    FROM Foo
)
SELECT *
FROM RankedRows
WHERE row_num = 1;

PostgreSQL 实现方式

除了通用的窗口函数写法,还能用上PostgreSQL专属的DISTINCT ON语法,更简洁:

-- 通用窗口函数写法
SELECT *
FROM (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY DeviceId, TransactionId, IndetId, Datetime, SalesId 
                              ORDER BY (SELECT 1)) AS row_num
    FROM Foo
) AS temp
WHERE row_num = 1;

-- PostgreSQL专属简洁写法
SELECT DISTINCT ON (DeviceId, TransactionId, IndetId, Datetime, SalesId) *
FROM Foo
ORDER BY DeviceId, TransactionId, IndetId, Datetime, SalesId;

DISTINCT ON会保留每组排序后的第一行,ORDER BY必须先写分组列,后面可追加其他排序规则。

关键注意点

  • 要是你需要“首行”是符合特定逻辑的行(比如最早创建时间、最大Quantity),一定要在ORDER BY里明确指定对应列,不然数据库返回的首行是随机的。
  • 别直接用GROUP BY,因为它要求非聚合列都得在分组条件里,没法返回所有列,满足不了需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:30:42