go gorm select 用了group by和order by,返回的数据与原struct 类型不同,导致返回数据无用。

新手上路,请多包涵

go gorm select 用了group by和order by,返回的数据与原struct 类型不同,导致返回数据无用,求大佬指点?

以下是我的数据库中一个表的 struct 信息,是服务告警信息:

type Alarm struct {
    gorm.Model
    EventId    string
    AlarmTime  time.Time
    Priority   int
    Status     string
    TplId      int
    StraId     int
    ExpId      int
    Metric     string
    Tags       string
    LeftValue  string
    RightValue string
    Endpoint   string
    Step       int
    Note       string `gorm:"size: 500"`
    Pdl        string
    Domain     string
    Path       string
    Cluster    string
   }

我对数据库的一个字段进行了Group by操作

func (topTime TopfiveTime) GetIncidentsfive(mark string) []Alarm{
    var topFiveList []Alarm
    topStartTime, _ := parseWithLocation("Asia/Shanghai", topTime.StartTime)
    topEndTime, _ :=  parseWithLocation("Asia/Shanghai", topTime.EndTime)

    db.Select(mark + ",count(*) AS mark_cnt").
        Where("status = 'problem' AND created_at BETWEEN ? AND ?",topStartTime, topEndTime).
        Group(mark).
        Order("mark_cnt DESC").
        Limit(6).
        Find(&topFiveList)
        fmt.Println(topFiveList)

    return topFiveList
    }

上述函数是执行select SQL的语句,在数据库执行结果如下:
图片描述

但是,由于生成的结果与Alarm struct不一致了,导致返回的信息是一些不可用数据(原Alarm 数据表中的无用数据),
求大佬解释如何能正确返回所需要的信息,如数据库展示的那样?

阅读 26k
2 个回答
新手上路,请多包涵

在定义一个结构体,

type Statistics struct{

Mark
MarkCnt

}

var statistics []Statistics
查询语句用
db.TableName("alarms").Select(mark + " as mark,count(*) AS mark_cnt").

    Where("status = 'problem' AND created_at BETWEEN ? AND ?",topStartTime, topEndTime).
    Group(mark).
    Order("mark_cnt DESC").
    Limit(6).
    Find(&statistics)

你可以这样做

//定义新的返回结构体
type Result struct {
    ServerAvailable int
    Qps             int
    DfBytesFreePerc int
    Load1Min        int
    StatusCode5xx   int
    DiskIoUtil      int
}
func (topTime TopfiveTime) GetIncidentsfive(mark string) (result []Result){

    topStartTime, _ := parseWithLocation("Asia/Shanghai", topTime.StartTime)
    topEndTime, _ :=  parseWithLocation("Asia/Shanghai", topTime.EndTime)

    db.Select(mark + ",count(*) AS mark_cnt").
        Where("status = 'problem' AND created_at BETWEEN ? AND ?",topStartTime, topEndTime).
        Group(mark).
        Order("mark_cnt DESC").
        Limit(6).
        Scan(&result)
        fmt.Println(result)

    return 
    }

上面的代码不一定能运行,但是大体思路是这样的

1.首先定义一个新的结构体用于解析查询返回,也就是上面定义的 Reslut

2.使用 Scan(&reslut) 进行赋值解析

当然有一点必须遵守 ,就是重新定义的结构体里面的内容的名称,如 ServerAvailable ,他们必须和 sql 查询返回的值的名称相对应

为了帮助你理解给你一张我项目中的截图

clipboard.png

其中 AllImageStore 的定义为

type AllImageStore struct {
    Sid   uint   `json:"-"`
    Name  string `json:"name"`
    Total int    `json:"total"`
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题