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

Oracle Distinct查询需求:按年份统计唯一客户并保留其他列数据

解决方案:按年份去重客户并保留所有列(无GROUP BY)

你的问题核心是没有把年份(Year)纳入去重维度——原来的SELECT DISTINCT(CustomerID)只会对客户ID去重,完全忽略了年份,导致同一个客户跨不同年份只会显示一次,这显然不符合需求。下面给你两种不需要GROUP BY的实现方案,按需选择:

方案1:保留每年每个客户的单条记录(优先推荐)

如果希望同一年同一个客户只显示一条记录(不管其他业务字段的差异,比如取该客户当年的第一条访问记录),用ROW_NUMBER()窗口函数是最稳妥的方式:

SELECT *
FROM (
    SELECT 
        *,
        -- 按年份+客户ID分区,给每个分区的行编号
        ROW_NUMBER() OVER (PARTITION BY Year, CustomerID ORDER BY CustomerVisitID) AS row_num
    FROM CustomerVisits
    WHERE Year IN (2016,2017,2018,2019)
) AS visit_subquery
-- 只取每个分区的第一条记录
WHERE row_num = 1;

说明:

  • PARTITION BY Year, CustomerID:把数据按「年份+客户ID」分成不同的组,每个组对应一个客户的某一年访问记录
  • ORDER BY CustomerVisitID:决定每个组里哪条记录排在最前面(这里用访问ID,你也可以换成业务需要的字段,比如按访问时间排序取最新/最早的记录)
  • 外层筛选row_num = 1,就能保证每年每个客户只保留一条记录,同时完整保留所有业务列数据

方案2:保留每年每个客户的所有唯一业务组合

如果业务上需要保留同一年同一个客户的所有不同业务字段组合(比如同一个客户同一年有不同的业务操作,需要全部展示,但重复的组合要去重),可以用多列DISTINCT:

-- 注意:必须明确列出需要保留的列,不能用SELECT *
SELECT DISTINCT 
    CustomerID, 
    Year, 
    BusinessField1, 
    BusinessField2,
    -- 其他需要保留的业务字段
FROM CustomerVisits
WHERE Year IN (2016,2017,2018,2019);

说明:

  • 这里的DISTINCT会基于所有列出的列去重,只有当所有列的值都完全相同时才会合并行
  • 不能用SELECT *,因为CustomerVisitID是唯一的,会导致所有行都被保留,失去去重效果

为什么原来的查询失效?

DISTINCT(CustomerID)本质上和DISTINCT CustomerID是一样的,只会根据客户ID这一列去重,完全不考虑年份维度。所以像CustomerID "5544"这样在2016和2018都有访问的客户,会被合并成一条记录,而不是按年份各显示一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:43:13