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

Oracle SQL单查询按用户统计资质数及获取最新资质

问题根因

窗口函数的计算逻辑是为原表中每一行数据单独返回计算结果,不会做分组聚合去重。你当前的写法没有做分组或行过滤,所以有多少条原始资质记录就会返回多少行,自然持有2条资质的userid=One会返回2条记录,不符合单用户单行的预期。
另外你原SQL里的表名Qualificaitons存在拼写错误,执行时会触发对象不存在的报错,正确表名应为Qualifications。

正确实现SQL

以下两种单查询写法均可满足需求,其中第一种是Oracle场景下性能最优的原生写法:

方案1:GROUP BY + KEEP 聚合(推荐)

直接按userid分组,用普通聚合函数统计资质总数,通过Oracle专属的KEEP子句直接取每个用户最新日期对应的资质,无需嵌套子查询:

SELECT
  userid,
  COUNT(qualification) AS count_qual,
  MAX(qualification) KEEP (DENSE_RANK FIRST ORDER BY "date" DESC) AS latest_qual
FROM Qualifications
GROUP BY userid;

语法说明:DENSE_RANK FIRST ORDER BY "date" DESC会先筛选出每个用户分组下日期最大(即最新获得)的资质记录集,再对该集合内的qualification取MAX值;如果存在同一用户同一天获得多个资质的场景,会返回名称排序最大的资质,保证结果确定性。注意date是Oracle保留关键字,作为字段名使用时需要加双引号。

方案2:窗口函数+外层过滤

如果偏好窗口函数写法,可以先在子查询中计算每个用户的资质总数、同时给每个用户的资质记录按获得日期倒序编排名,外层只取排名为1的最新记录即可:

SELECT userid, count_qual, qualification AS latest_qual
FROM (
  SELECT
    userid,
    qualification,
    COUNT(qualification) OVER (PARTITION BY userid) AS count_qual,
    ROW_NUMBER() OVER (PARTITION BY userid ORDER BY "date" DESC, qualification DESC) AS rn
  FROM Qualifications
)
WHERE rn = 1;

注意点:ROW_NUMBER排序时增加了qualification DESC作为兜底排序规则,避免同一用户同一天获得多条资质时返回结果不确定。

执行结果

针对你提供的测试数据,上述两种SQL返回的结果完全符合预期:

  • userid=One:count_qual=2,latest_qual=Qual2
  • userid=Two:count_qual=1,latest_qual=Qual1
  • userid=Three:count_qual=1,latest_qual=Qual2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:09:25