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

使用Gorm执行PostgreSQL原生sum查询时字段值为0的问题

问题描述

我在PostgreSQL中执行以下原生查询:

SELECT 
  at."category" AS "category", 
  at."month" AS "month", 
  sum(at.price_aft_discount) as "sum", 
  sum(at.qty_ordered) as "sum2" 
FROM 
  all_trans at 
GROUP BY 
  at."category", 
  at."month" 
ORDER BY 
  at."category" ASC, 
  at."month" asc

在DBeaver中能得到正确的非零聚合结果,但sum和sum2列显示类型为numeric(131089,0),且提示「无对应表列」。

使用Go语言的Gorm框架查询时,定义了如下结构体:

type ATQueryResult struct {
   category string  `gorm:"column:category"`
   month    string  `gorm:"column:month"`
   sum      float32 `gorm:"column:sum"`
   sum2     float32 `gorm:"column:sum2"`
}

queryString := ... // 上述SQL语句
var result []ATQueryResult

db.Table(model.TableAllTrans).Raw(queryString).Find(&result)

fmt.Println(result[3])

执行后所有result[i].sum和result[i].sum2的值均为0,需要解决字段映射异常问题。

问题原因
  1. 类型不匹配:PostgreSQL的sum()函数返回numeric类型(聚合大量数据时精度极高),而结构体中使用float32类型,Gorm在类型转换时失败,默认赋值为0。
  2. (次要)字段名大小写敏感:SQL中别名使用双引号包裹("sum"),若PostgreSQL开启标识符大小写敏感,结构体标签中无引号的sum可能无法匹配列名。
解决方案

方案1:使用对应Go类型适配PostgreSQL numeric

PostgreSQL的numeric类型推荐使用github.com/shopspring/decimal库的Decimal类型进行映射,避免精度丢失和转换失败:

  1. 安装依赖:
go get github.com/shopspring/decimal
  1. 修改结构体:
import "github.com/shopspring/decimal"

type ATQueryResult struct {
   category string          `gorm:"column:category"`
   month    string          `gorm:"column:month"`
   sum      decimal.Decimal `gorm:"column:sum"`
   sum2     decimal.Decimal `gorm:"column:sum2"`
}
  1. 如需转换为float32使用:
sumFloat, _ := result[3].sum.Float32()
sum2Float, _ := result[3].sum2.Float32()

方案2:SQL中显式转换为float类型

若确认数据精度不会丢失,可在SQL中将聚合结果直接转为float类型:

SELECT 
  at."category" AS "category", 
  at."month" AS "month", 
  sum(at.price_aft_discount)::float as "sum", 
  sum(at.qty_ordered)::float as "sum2" 
FROM 
  all_trans at 
GROUP BY 
  at."category", 
  at."month" 
ORDER BY 
  at."category" ASC, 
  at."month" asc

修改后结构体中的float32即可正确映射。

方案3:修正字段名映射(针对大小写敏感场景)

若PostgreSQL因双引号导致列名大小写敏感,可修改结构体标签为带引号的形式:

type ATQueryResult struct {
   category string  `gorm:"column:\"category\""`
   month    string  `gorm:"column:\"month\""`
   sum      float32 `gorm:"column:\"sum\""`
   sum2     float32 `gorm:"column:\"sum2\""`
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:40:28