HQL查询:按c_id去重 每个c_id仅返回单条记录实现方法
HQL 按c_id去重返回单条记录实现方案
首先明确你提到的两种语法的适用限制,二者都不能直接满足当前场景需求:
DISTINCT:仅对整行所有字段值完全一致的重复数据生效,你当前同c_id对应的银行账号、账户状态字段存在不同值,直接加distinct无法实现按c_id维度去重的效果。GROUP BY c_id:标准HQL语法要求,select后的非分组字段必须包裹在聚合函数内,直接写其余字段要么触发语法报错,要么在非严格校验模式下随机返回组内某条值,无法稳定得到你预期的固定结果。
推荐实现写法
你的需求本质是给每个c_id分组下的记录做排序,取排序后的第一条,用row_number()窗口函数实现最稳定,支持自定义取数规则,不会出现随机返回的问题。
假设你的原始表名为customer_bank_acc,对应HQL写法如下:
select c_id, country, birth_date, bank_account, state_of_bank_acc, ddate from ( select *, row_number() over ( partition by c_id order by case when state_of_bank_acc = 'inactive' then 0 else 1 end, bank_account desc ) as rn from customer_bank_acc ) tmp where rn = 1;
逻辑说明
partition by c_id:按c_id字段做逻辑分组,和group by的分组维度一致- 排序规则和你给出的目标结果完全对齐:优先取账户状态为inactive的记录,同状态下按银行账号倒序取第一条,最终b_111返回FR991开头的active账号、c_999返回DEU777开头的inactive账号、n_777直接返回唯一一条记录
- 外层过滤
rn=1即取每个分组排序后的第一条记录 - 你可以根据实际业务需求调整排序规则,比如要取最早入库的记录就按入库时间字段升序排,要优先取其他状态的记录可以修改case when的优先级定义,都能稳定返回每个c_id对应的单条结果。
内容的提问来源于stack exchange,提问作者Hiver
相关产品推荐
相关产品推荐

