Golang Bun执行GROUP BY分组统计仅返回单条结果问题求助
问题:Golang Bun分组统计查询仅返回单条结果
问题场景
使用Bun ORM执行按state分组并统计数量的查询时,原生SQL可返回两行结果,但Go代码仅获取到第一行数据。
原生SQL语句
SELECT state, count(*) FROM "jobs" AS "j" GROUP BY "state"
预期执行结果
state,count 2,1 1,1
原Go Bun代码
func FindJobGroups(db *bun.DB, ctx context.Context) (map[string]interface{}, error) { m := make(map[string]interface{}) err := db.NewSelect().Model((*Job)(nil)).ColumnExpr("state, count(*)").Group("state").Scan(ctx, &m) return m, err }
调试生成的SQL(符合预期)
[bun] 16:18:59.626 SELECT 592µs SELECT state, count(*) FROM "jobs" AS "j" GROUP BY "state"
实际返回结果(仅第一条)
1 = count -> 1 0 = state -> 2
Job结构体定义
type Job struct { bun.BaseModel `bun:"table:jobs,alias:j"` ID int64 `bun:",pk,autoincrement"` State int64 `json:"state"` }
解决方案
问题出在用单个map[string]interface{}接收多行结果:Bun会将每行数据依次映射到同一个map,后续行的键值对会覆盖之前的,最终仅保留最后处理的一行数据。
正确的做法是使用切片+专用结构体来接收所有分组结果:
1. 定义统计结果结构体
创建对应查询列的结构体,字段名与查询结果的列名(或别名)一致:
// 用于接收分组统计结果的结构体 type JobStateCount struct { State int64 `bun:"state"` // 对应查询的state列 Count int64 `bun:"count"` // 对应count(*)的别名count }
2. 修改查询函数
用切片[]JobStateCount来接收多行结果,同时给count(*)指定别名以匹配结构体字段:
func FindJobGroups(db *bun.DB, ctx context.Context) ([]JobStateCount, error) { var stateCounts []JobStateCount err := db.NewSelect(). Model((*Job)(nil)). ColumnExpr("state, count(*) as count"). // 给count(*)起别名count,对应结构体字段 Group("state"). Scan(ctx, &stateCounts) return stateCounts, err }
最终返回结果
执行后将得到与原生SQL一致的完整结果:
[]JobStateCount{ {State: 2, Count: 1}, {State: 1, Count: 1}, }
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

