MirkoORM中按type分组获取各类型最高version证书的问题
问题分析与解决方法
错误原因
你的两次查询都没抓住GROUP BY的核心逻辑:
- 第一次查询只按
type分组,但SELECT里包含了非聚合列version,SQL标准要求非聚合列必须出现在GROUP BY中,否则数据库无法确定要返回同类型下的哪一个版本值,因此报错。 - 把
version加入GROUP BY后,分组依据变成了type + version的组合,每个不同的版本都会形成独立分组,自然会返回同一类型下的所有版本记录,完全偏离了“取最高版本”的需求。
正确解法
根据你的需求,分两种场景给出方案:
场景1:仅需每个类型的最高版本值
直接用MAX()聚合函数获取每个type对应的最大version,配合GROUP BY type即可:
const r = await this.em.createQueryBuilder(CertificateEntity) .select(['type', 'MAX(version) as maxVersion']) .groupBy('type') .execute();
执行后会得到类似结果:
[ { "type": "s-type", "maxVersion": 1.7 } ]
场景2:需要获取最高版本对应的完整证书记录(含name、description等)
这时候需要先通过子查询找出每个类型的最高版本,再关联原表匹配完整数据:
const r = await this.em.createQueryBuilder(CertificateEntity, 'c') .select(['c.*']) .where('(c.type, c.version) IN (SELECT type, MAX(version) FROM certificates GROUP BY type)') .execute();
或者用窗口函数ROW_NUMBER()更灵活(支持同类型多个相同最高版本的场景):
const r = await this.em.createQueryBuilder(CertificateEntity, 'c') .select(['sub.*']) .from(subquery => { return subquery .select(['c.*', 'ROW_NUMBER() OVER (PARTITION BY c.type ORDER BY c.version DESC) as rn']) .from(CertificateEntity, 'c'); }, 'sub') .where('sub.rn = 1') .execute();
内容的提问来源于stack exchange,提问作者Mike M
相关产品推荐
相关产品推荐

