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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 03:20:28