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

TypeORM使用QueryBuilder执行group by分组统计时报错如何解决

TypeORM QueryBuilder分组查询报错解决方案

报错根因

  • 语法错误:你写的SUM(balance.amount缺少右括号,导致生成的SQL语句函数未闭合,直接触发PostgreSQL 42601语法错误码
  • 逻辑错误:使用leftJoinAndSelect会自动加载balance、token两个实体的全部字段到SELECT列表,而GROUP BY仅指定了balance.tokenId,不符合SQL分组规范(未聚合的非分组字段不允许出现在SELECT列表中)

修正后代码

import { EntityRepository, Repository } from "typeorm";
import { Address } from "../../../entity";
import { Balance } from "../../../entity/Balance";

@EntityRepository(Balance)
export class BalanceRepository extends Repository<Balance> {
  async findByAddress(address: Address): Promise<{amount: string, token: number|string}[]> {
    return this.createQueryBuilder("balance")
      .select("SUM(balance.amount)", "amount")
      // 如果要返回token symbol就把下面的token.id换成token.symbol
      .addSelect("token.id", "token")
      .leftJoin("balance.token", "token")
      // 新增指定address的过滤条件
      .where("balance.addressId = :addressId", { addressId: address.id })
      .groupBy("token.id")
      .getRawMany();
  }
}

调整说明

  • 补全SUM函数的闭合括号,修复基础语法错误
  • 替换leftJoinAndSelect为leftJoin,避免加载不必要的实体字段,适配分组查询要求
  • 显式指定需要返回的聚合结果和关联字段,非聚合的token字段同步加入GROUP BY列表,符合SQL标准
  • 新增where条件通过外键addressId过滤指定地址的余额记录,满足你后续的过滤需求
  • 输出格式直接匹配你要求的结构,可通过修改addSelect的字段灵活切换返回tokenId还是token.symbol

注意事项

你定义的amount字段是numeric类型,聚合后返回结果为字符串格式,可避免大数字精度丢失,如果业务要求数字类型可自行转换,大额资产建议优先用字符串存储传输。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:36:06