forked from mirror/gorm
Add GroupBy test
This commit is contained in:
parent
ce0e6f9f33
commit
a158d1ada0
|
@ -135,14 +135,20 @@ func (db *DB) Joins(query string, args ...interface{}) (tx *DB) {
|
|||
}
|
||||
|
||||
// Group specify the group method on the find
|
||||
func (db *DB) Group(column string) (tx *DB) {
|
||||
func (db *DB) Group(name string) (tx *DB) {
|
||||
tx = db.getInstance()
|
||||
tx.Statement.AddClause(clause.GroupBy{
|
||||
Columns: []clause.Column{{Name: name}},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Having specify HAVING conditions for GROUP BY
|
||||
func (db *DB) Having(query interface{}, args ...interface{}) (tx *DB) {
|
||||
tx = db.getInstance()
|
||||
tx.Statement.AddClause(clause.GroupBy{
|
||||
Having: tx.Statement.BuildCondtion(query, args...),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ func BenchmarkComplexSelect(b *testing.B) {
|
|||
clause.Where{Exprs: []clause.Expression{
|
||||
clause.Or(clause.Gt{Column: "score", Value: 100}, clause.Like{Column: "name", Value: "%linus%"}),
|
||||
}},
|
||||
clause.GroupBy{Columns: []clause.Column{{Name: "role"}}, Having: clause.Where{[]clause.Expression{clause.Eq{"role", "admin"}}}},
|
||||
clause.GroupBy{Columns: []clause.Column{{Name: "role"}}, Having: []clause.Expression{clause.Eq{"role", "admin"}}},
|
||||
clause.Limit{Limit: 10, Offset: 20},
|
||||
clause.OrderBy{Columns: []clause.OrderByColumn{{Column: clause.PrimaryColumn, Desc: true}}},
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package clause
|
|||
// GroupBy group by clause
|
||||
type GroupBy struct {
|
||||
Columns []Column
|
||||
Having Where
|
||||
Having []Expression
|
||||
}
|
||||
|
||||
// Name from clause name
|
||||
|
@ -21,9 +21,9 @@ func (groupBy GroupBy) Build(builder Builder) {
|
|||
builder.WriteQuoted(column)
|
||||
}
|
||||
|
||||
if len(groupBy.Having.Exprs) > 0 {
|
||||
if len(groupBy.Having) > 0 {
|
||||
builder.Write(" HAVING ")
|
||||
groupBy.Having.Build(builder)
|
||||
Where{Exprs: groupBy.Having}.Build(builder)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ func (groupBy GroupBy) Build(builder Builder) {
|
|||
func (groupBy GroupBy) MergeClause(clause *Clause) {
|
||||
if v, ok := clause.Expression.(GroupBy); ok {
|
||||
groupBy.Columns = append(v.Columns, groupBy.Columns...)
|
||||
groupBy.Having.Exprs = append(v.Having.Exprs, groupBy.Having.Exprs...)
|
||||
groupBy.Having = append(v.Having, groupBy.Having...)
|
||||
}
|
||||
clause.Expression = groupBy
|
||||
}
|
||||
|
|
|
@ -16,17 +16,17 @@ func TestGroupBy(t *testing.T) {
|
|||
{
|
||||
[]clause.Interface{clause.Select{}, clause.From{}, clause.GroupBy{
|
||||
Columns: []clause.Column{{Name: "role"}},
|
||||
Having: clause.Where{[]clause.Expression{clause.Eq{"role", "admin"}}},
|
||||
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.Where{[]clause.Expression{clause.Eq{"role", "admin"}}},
|
||||
Having: []clause.Expression{clause.Eq{"role", "admin"}},
|
||||
}, clause.GroupBy{
|
||||
Columns: []clause.Column{{Name: "gender"}},
|
||||
Having: clause.Where{[]clause.Expression{clause.Neq{"gender", "U"}}},
|
||||
Having: []clause.Expression{clause.Neq{"gender", "U"}},
|
||||
}},
|
||||
"SELECT * FROM `users` GROUP BY `role`,`gender` HAVING `role` = ? AND `gender` <> ?", []interface{}{"admin", "U"},
|
||||
},
|
||||
|
|
|
@ -145,12 +145,6 @@ func (db *DB) Delete(value interface{}, conds ...interface{}) (tx *DB) {
|
|||
return
|
||||
}
|
||||
|
||||
//Preloads only preloads relations, don`t touch out
|
||||
func (db *DB) Preloads(out interface{}) (tx *DB) {
|
||||
tx = db.getInstance()
|
||||
return
|
||||
}
|
||||
|
||||
func (db *DB) Count(value interface{}) (tx *DB) {
|
||||
tx = db.getInstance()
|
||||
return
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
func TestGroupBy(t *testing.T, db *gorm.DB) {
|
||||
db.Migrator().DropTable(&User{})
|
||||
db.AutoMigrate(&User{})
|
||||
|
||||
t.Run("GroupBy", func(t *testing.T) {
|
||||
var users = []User{{
|
||||
Name: "groupby",
|
||||
Age: 10,
|
||||
Birthday: Now(),
|
||||
}, {
|
||||
Name: "groupby",
|
||||
Age: 20,
|
||||
Birthday: Now(),
|
||||
}, {
|
||||
Name: "groupby",
|
||||
Age: 30,
|
||||
Birthday: Now(),
|
||||
}, {
|
||||
Name: "groupby1",
|
||||
Age: 110,
|
||||
Birthday: Now(),
|
||||
}, {
|
||||
Name: "groupby1",
|
||||
Age: 220,
|
||||
Birthday: Now(),
|
||||
}, {
|
||||
Name: "groupby1",
|
||||
Age: 330,
|
||||
Birthday: Now(),
|
||||
}}
|
||||
|
||||
if err := db.Create(&users).Error; err != nil {
|
||||
t.Errorf("errors happened when create: %v", err)
|
||||
}
|
||||
|
||||
var name string
|
||||
var total int
|
||||
if err := db.Model(&User{}).Select("name, sum(age)").Where("name = ?", "groupby").Group("name").Row().Scan(&name, &total); err != nil {
|
||||
t.Errorf("no error should happen, but got %v", err)
|
||||
}
|
||||
|
||||
if name != "groupby" || total != 60 {
|
||||
t.Errorf("name should be groupby, but got %v, total should be 60, but got %v", name, total)
|
||||
}
|
||||
|
||||
if err := db.Model(&User{}).Select("name, sum(age) as total").Where("name LIKE ?", "groupby%").Group("name").Having("name = ?", "groupby1").Row().Scan(&name, &total); err != nil {
|
||||
t.Errorf("no error should happen, but got %v", err)
|
||||
}
|
||||
|
||||
if name != "groupby1" || total != 660 {
|
||||
t.Errorf("name should be groupby, but got %v, total should be 660, but got %v", name, total)
|
||||
}
|
||||
})
|
||||
}
|
|
@ -20,6 +20,8 @@ func RunTestsSuit(t *testing.T, db *gorm.DB) {
|
|||
TestFind(t, db)
|
||||
TestUpdate(t, db)
|
||||
TestDelete(t, db)
|
||||
|
||||
TestGroupBy(t, db)
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T, db *gorm.DB) {
|
||||
|
|
Loading…
Reference in New Issue