Oracle中Group By字段少于Select字段报错,如何查询用户最长时长匹配记录
问题原因说明
你原来的SQL报错核心有两个问题:
- Oracle要求
GROUP BY子句必须包含SELECT中所有未被聚合函数包裹的字段,你只写了GROUP BY A.ID,但查询了A.NAME,不符合语法规则。 - 就算修正GROUP BY语法,也没法直接返回对应最大时长的
MATCH_CODE字段,因为把MATCH_CODE加入GROUP BY会把分组粒度拆成「用户+匹配编码」,达不到取每个用户单条最大时长记录的需求。
另外你计算时间差的写法过于繁琐,还容易出现括号不匹配的语法问题:Oracle中两个DATE类型相减直接返回相差的天数,乘以86400(24*60*60)就能直接得到秒级差值,不需要层层extract取值。
正确实现方案
用窗口函数ROW_NUMBER()实现按用户分组取TOP1记录的需求,代码如下:
SELECT ID, NAME, MATCH_CODE, max_differance FROM ( SELECT A.ID, A.NAME, B.MATCH_CODE, (B.END_DATE - B.START_DATE) * 86400 AS max_differance, -- 按用户ID分组,按匹配时长倒序排序,序号1就是每个用户时长最大的记录 ROW_NUMBER() OVER (PARTITION BY A.ID ORDER BY (B.END_DATE - B.START_DATE) DESC) AS rn FROM "USER" A INNER JOIN MATCH B ON A.ID = B.ID_USER ) t WHERE rn = 1;
补充说明
- 注意
USER是Oracle的内置关键字,作为表名使用时需要加双引号包裹。 - 如果某个用户存在多条时长完全相同的最大匹配记录,想要全部返回的话,把
ROW_NUMBER()替换成RANK()即可。
内容的提问来源于stack exchange,提问作者Fesilox
相关产品推荐
相关产品推荐

