Go gorm select uses group by and order by, and the returned data is different from the original struct type, causing the returned data to be useless.

go gorm select uses group by and order by, and the returned data is different from the original struct type, so the returned data is useless.

the following is the struct information of a table in my database, which is the service alarm information:

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
   }

I Group by a field in the database

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
    }

the above function is a statement that executes select SQL. The result of execution in the database is as follows:

however, because the generated result is inconsistent with Alarm struct , the information returned is some unavailable data (useless data in the original Alarm data table).
asks the boss to explain how to return the required information correctly, as shown in the database.

Jul.02,2022

defining a structure,

type Statistics struct {

Mark
MarkCnt

}

var statistics [] Statistics
query statement use
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)

you can do this

//
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 
    }

the above code may not work, but the general idea goes like this

1. First define a new structure to parse the query return, that is, Reslut

defined above

2. Use Scan (& reslut) to resolve assignments

Of course, the

must comply with the name of the content in the redefined structure, such as ServerAvailable , which must correspond to the name of the value returned by the sql query

.

to help you understand, I'll give you a screenshot of my project

clipboard.png

where AllImageStore is defined as

type AllImageStore struct {
    Sid   uint   `json:"-"`
    Name  string `json:"name"`
    Total int    `json:"total"`
}
Menu