mirror of https://github.com/go-gorm/gorm.git
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
|
// 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 = db.getInstance()
|
||||||
|
tx.Statement.AddClause(clause.GroupBy{
|
||||||
|
Columns: []clause.Column{{Name: name}},
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Having specify HAVING conditions for GROUP BY
|
// Having specify HAVING conditions for GROUP BY
|
||||||
func (db *DB) Having(query interface{}, args ...interface{}) (tx *DB) {
|
func (db *DB) Having(query interface{}, args ...interface{}) (tx *DB) {
|
||||||
tx = db.getInstance()
|
tx = db.getInstance()
|
||||||
|
tx.Statement.AddClause(clause.GroupBy{
|
||||||
|
Having: tx.Statement.BuildCondtion(query, args...),
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ func BenchmarkComplexSelect(b *testing.B) {
|
||||||
clause.Where{Exprs: []clause.Expression{
|
clause.Where{Exprs: []clause.Expression{
|
||||||
clause.Or(clause.Gt{Column: "score", Value: 100}, clause.Like{Column: "name", Value: "%linus%"}),
|
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.Limit{Limit: 10, Offset: 20},
|
||||||
clause.OrderBy{Columns: []clause.OrderByColumn{{Column: clause.PrimaryColumn, Desc: true}}},
|
clause.OrderBy{Columns: []clause.OrderByColumn{{Column: clause.PrimaryColumn, Desc: true}}},
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package clause
|
||||||
// GroupBy group by clause
|
// GroupBy group by clause
|
||||||
type GroupBy struct {
|
type GroupBy struct {
|
||||||
Columns []Column
|
Columns []Column
|
||||||
Having Where
|
Having []Expression
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name from clause name
|
// Name from clause name
|
||||||
|
@ -21,9 +21,9 @@ func (groupBy GroupBy) Build(builder Builder) {
|
||||||
builder.WriteQuoted(column)
|
builder.WriteQuoted(column)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(groupBy.Having.Exprs) > 0 {
|
if len(groupBy.Having) > 0 {
|
||||||
builder.Write(" HAVING ")
|
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) {
|
func (groupBy GroupBy) MergeClause(clause *Clause) {
|
||||||
if v, ok := clause.Expression.(GroupBy); ok {
|
if v, ok := clause.Expression.(GroupBy); ok {
|
||||||
groupBy.Columns = append(v.Columns, groupBy.Columns...)
|
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
|
clause.Expression = groupBy
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,17 +16,17 @@ func TestGroupBy(t *testing.T) {
|
||||||
{
|
{
|
||||||
[]clause.Interface{clause.Select{}, clause.From{}, clause.GroupBy{
|
[]clause.Interface{clause.Select{}, clause.From{}, clause.GroupBy{
|
||||||
Columns: []clause.Column{{Name: "role"}},
|
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"},
|
"SELECT * FROM `users` GROUP BY `role` HAVING `role` = ?", []interface{}{"admin"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]clause.Interface{clause.Select{}, clause.From{}, clause.GroupBy{
|
[]clause.Interface{clause.Select{}, clause.From{}, clause.GroupBy{
|
||||||
Columns: []clause.Column{{Name: "role"}},
|
Columns: []clause.Column{{Name: "role"}},
|
||||||
Having: clause.Where{[]clause.Expression{clause.Eq{"role", "admin"}}},
|
Having: []clause.Expression{clause.Eq{"role", "admin"}},
|
||||||
}, clause.GroupBy{
|
}, clause.GroupBy{
|
||||||
Columns: []clause.Column{{Name: "gender"}},
|
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"},
|
"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
|
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) {
|
func (db *DB) Count(value interface{}) (tx *DB) {
|
||||||
tx = db.getInstance()
|
tx = db.getInstance()
|
||||||
return
|
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)
|
TestFind(t, db)
|
||||||
TestUpdate(t, db)
|
TestUpdate(t, db)
|
||||||
TestDelete(t, db)
|
TestDelete(t, db)
|
||||||
|
|
||||||
|
TestGroupBy(t, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreate(t *testing.T, db *gorm.DB) {
|
func TestCreate(t *testing.T, db *gorm.DB) {
|
||||||
|
|
Loading…
Reference in New Issue