本文次要钻研一下gorm的GroupBy

GroupBy

gorm.io/gorm@v1.20.11/clause/group_by.go

// GroupBy group by clausetype GroupBy struct {    Columns []Column    Having  []Expression}// Name from clause namefunc (groupBy GroupBy) Name() string {    return "GROUP BY"}// Build build group by clausefunc (groupBy GroupBy) Build(builder Builder) {    for idx, column := range groupBy.Columns {        if idx > 0 {            builder.WriteByte(',')        }        builder.WriteQuoted(column)    }    if len(groupBy.Having) > 0 {        builder.WriteString(" HAVING ")        Where{Exprs: groupBy.Having}.Build(builder)    }}// MergeClause merge group by clausefunc (groupBy GroupBy) MergeClause(clause *Clause) {    if v, ok := clause.Expression.(GroupBy); ok {        copiedColumns := make([]Column, len(v.Columns))        copy(copiedColumns, v.Columns)        groupBy.Columns = append(copiedColumns, groupBy.Columns...)        copiedHaving := make([]Expression, len(v.Having))        copy(copiedHaving, v.Having)        groupBy.Having = append(copiedHaving, groupBy.Having...)    }    clause.Expression = groupBy}
GroupBy定义了Columns和Having属性,其Build办法遍历Columns,最初针对Having在拼接Having子句

实例

func TestGroupBy(t *testing.T) {    results := []struct {        Clauses []clause.Interface        Result  string        Vars    []interface{}    }{        {            []clause.Interface{clause.Select{}, clause.From{}, clause.GroupBy{                Columns: []clause.Column{{Name: "role"}},                Having:  []clause.Expression{clause.Eq{"role", "admin"}},            }},            "SELECT * FROM `users` GROUP BY `role` HAVING `role` = ?", []interface{}{"admin"},        },        {            []clause.Interface{clause.Select{}, clause.From{}, clause.GroupBy{                Columns: []clause.Column{{Name: "role"}},                Having:  []clause.Expression{clause.Eq{"role", "admin"}},            }, clause.GroupBy{                Columns: []clause.Column{{Name: "gender"}},                Having:  []clause.Expression{clause.Neq{"gender", "U"}},            }},            "SELECT * FROM `users` GROUP BY `role`,`gender` HAVING `role` = ? AND `gender` <> ?", []interface{}{"admin", "U"},        },    }    for idx, result := range results {        t.Run(fmt.Sprintf("case #%v", idx), func(t *testing.T) {            checkBuildClauses(t, result.Clauses, result.Result, result.Vars)        })    }}

小结

gorm的GroupBy定义了Columns和Having属性,其Build办法遍历Columns,最初针对Having在拼接Having子句。

doc

  • gorm