MikroORM QueryBuilder查询报错:字段需在GROUP BY或聚合函数中
解决QueryBuilder聚合查询的GROUP BY报错问题
这个需求完全能用QueryBuilder实现,你遇到的报错是因为数据库(大概率是PostgreSQL)的SQL严格模式限制:当查询中包含聚合函数(比如你用的sum())时,所有非聚合的查询字段必须出现在GROUP BY子句中,否则数据库无法确定这些字段如何与聚合结果对应。
下面提供两种可行的修改方案:
方案一:添加GROUP BY子句
把所有非聚合字段加入GROUP BY,确保每个字段都被分组(建议同时包含用户表主键,保证分组的唯一性)。修改后的代码如下:
return this.qb('user') .where({ id }) .leftJoin('user.transactions', 'transactions') .leftJoin('user.wallet', 'wallet') .leftJoin('user.userLevel', 'userLevel') .select([ 'avatarUrl', 'otpEnabled', 'userName', 'profilePrivacy', 'userType', 'userLevel.level', 'loginType', 'createdAt', 'wallet.balance', this.qb() .where({ transactions: { transactionType: { name: TransactionTypeName.TipSent, }, }, }) .select('sum(transactions.amount)') .as('totalTipSent'), this.qb() .where({ transactions: { transactionType: { name: TransactionTypeName.TipReceived, }, }, }) .select('sum(transactions.amount)') .as('totalTipReceived'), ]) // 加入所有非聚合字段到GROUP BY .groupBy([ 'user.id', 'avatarUrl', 'otpEnabled', 'userName', 'profilePrivacy', 'userType', 'userLevel.level', 'loginType', 'createdAt', 'wallet.balance' ]) .execute('get');
方案二:用子查询独立计算聚合值
如果不想维护大量GROUP BY字段,可以将聚合逻辑拆到子查询中,主查询仅获取用户基础信息,再关联子查询的结果:
return this.qb('user') .where({ id }) .leftJoin('user.wallet', 'wallet') .leftJoin('user.userLevel', 'userLevel') .select([ 'avatarUrl', 'otpEnabled', 'userName', 'profilePrivacy', 'userType', 'userLevel.level', 'loginType', 'createdAt', 'wallet.balance', // 子查询计算总发送小费 (qb) => qb .select('sum(transactions.amount)') .from('transactions') .whereRaw('transactions.user_id = user.id') .where('transactions.transactionType.name', TransactionTypeName.TipSent) .as('totalTipSent'), // 子查询计算总接收小费 (qb) => qb .select('sum(transactions.amount)') .from('transactions') .whereRaw('transactions.user_id = user.id') .where('transactions.transactionType.name', TransactionTypeName.TipReceived) .as('totalTipReceived'), ]) .execute('get');
这种方式不需要GROUP BY,因为聚合计算是针对单个用户独立执行的子查询,主查询仅返回单条用户数据,从根源避免了分组限制。
两种方案都能实现你的需求,可根据实际场景选择:方案一写法直接,适合关联表较少的情况;方案二逻辑更清晰,在多关联场景下更易维护。
内容的提问来源于stack exchange,提问作者Bowis
相关产品推荐
相关产品推荐

