What version of Go are you using (go version)?
1.14
Which database and its version are you using?
msyql
Please provide a complete runnable program to reproduce your issue. IMPORTANT
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
var (
Dbo *gorm.DB
)
type User struct {
Id int64 `gorm:"type:bigint(11);column:id;primary_key;AUTO_INCREMENT;not null;"` //id
Name string `gorm:"type:varchar(50);column:name;not null;"` //name
}
func main() {
Dbo, _ = gorm.Open("mysql", "root:123456@(127.0.0.1:3306)/test?charset=utf8&parseTime=True&loc=Local")
Dbo.LogMode(true)
//query user
queryUser()
}
func queryUser() {
count := 0
users := make([]User, 0)
pageNo, pageSize := 1, 10 //page
err := Dbo.Table("user").
Where("id > 0").
Select("id,name").
Offset((pageNo - 1) * pageSize).
Limit(pageSize).
Order(" id asc ").Find(&users).Count(&count).Error
if err != nil {
panic(err)
}
fmt.Println(users)
fmt.Println(count)
}
when pageNo=1
SELECT id,name FROM user WHERE (id > 0) ORDER BY id asc LIMIT 10 OFFSET 0
10 rows affected or returned
SELECT count(*) FROM user WHERE (id > 0) LIMIT 10 OFFSET 0
when pageNo=2
SELECT id,name FROM user WHERE (id > 0) ORDER BY id asc LIMIT 10 OFFSET 10
2 rows affected or returned
SELECT count(*) FROMuserWHERE (id > 0) LIMIT 10 OFFSET 10
panic: sql: no rows in result set
Correct count sql statement is SELECT count(*) FROMuserWHERE (id > 0)
Comment From: nickchou
it can be solved using the Limit(-1),but is looks weird, can it be fixed the nex version of the framework?
err := Dbo.Table("user").
Where("id > ?",0).
Select("id,name").
Offset((pageNo - 1) * pageSize).
Limit(pageSize).
Order(" id asc ").Find(&users).
Limit(-1).
Count(&count).Error
Comment From: valebedu
I've got the same error:
var result []*someModel
var count *int64
if offset < 0 {
return nil, nil, errors.Errorf("offset: offset cannot be smaller than 0")
}
if limit < 1 || limit > 100 {
return nil, nil, errors.Errorf("limit: limit cannot be smaller than 1 or greater than 100")
}
tx := db.Offset(offset).Limit(limit)
if order != nil {
tx = tx.Order(*order)
}
if param != nil {
tx = tx.Where("param = ?", *param)
}
dbError := tx.Find(&result).Count(&count).Error
if dbError != nil {
return nil, nil, errors.Trace(dbError)
}
return result, count, nil
and obtain sql: no rows in result set when I set an offset greater than 0
Comment From: github-actions[bot]
This issue will be automatically closed because it is marked as GORM V1 issue, we have released the public testing GORM V2 release and its documents https://v2.gorm.io/docs/ already, the testing release has been used in some production services for a while, and going to release the final version in following weeks, we are still actively collecting feedback before it, please open a new issue for any suggestion or problem, thank you
Also check out https://github.com/go-gorm/gorm/wiki/GORM-V2-Release-Note-Draft for how to use the public testing version and its changelog
Comment From: Satan3
it can be solved using the Limit(-1),but is looks weird, can it be fixed the nex version of the framework?
err := Dbo.Table("user"). Where("id > ?",0). Select("id,name"). Offset((pageNo - 1) * pageSize). Limit(pageSize). Order(" id asc ").Find(&users). Limit(-1). Count(&count).Error
You can get count without limit and then set your limit and get users : err := Dbo.Table("user").
Where("id > ?",0). Select("id,name"). Count(&count). Offset((pageNo - 1) * pageSize). Limit(pageSize). Order(" id asc ").Find(&users)
Comment From: dreamer2q
The problem still exists, why leave it closed?
Comment From: XHPJ
err := Dbo.Table("user").
In my case I cannot use the Limit(-1) hack with Scopes, which make scopes and the advantages not useful for me anymore, which again is a pity.
err := models.DB.
Preload("association").
Scopes(models.Paginate(c)).
Find(&model).
Limit(-1).
Count(&count).
Error
Am I missing something in my case? 🤔
Comment From: fatelei
The problem still exists, why leave it closed?
yes, i meet this error, because statement not clone, reuse the stat select x from y offset z limit size
Comment From: wyudong
Try Offset(-1) to reset offset.
Comment From: jcconnell
err := Dbo.Table("user").
In my case I cannot use the
Limit(-1)hack with Scopes, which make scopes and the advantages not useful for me anymore, which again is a pity.
err := models.DB. Preload("association"). Scopes(models.Paginate(c)). Find(&model). Limit(-1). Count(&count). ErrorAm I missing something in my case? 🤔
I'm seeing the same behavior. If I use Scopes, Count fails. If instead I add the logic from the scopes as Where and Order, the query succeeds.
// this fails
result := db.Model(&models.Transaction{}).
Where("account_number = ?", actNum).
Scopes(
afterDate(startD),
beforeDate(endD),
orderBy("transaction_date", DESCENDING),
).
Count(&count).
Limit(PAGE_SIZE). // limit must come after count in order to get a total
Find(&ts)
With error: `ERROR: column "transactions.transaction_date" must appear in the GROUP BY clause or be used in an aggregate function (SQLSTATE 42803)
// this succeeds
result := db.Model(&models.Transaction{}).
Where("account_number = ?", actNum).
Where(dateAfterQuery, startD.In(dbconfig.TimeZoneHST)).
Where(dateBeforeQuery, endD.In(dbconfig.TimeZoneHST)).
Order(clause.OrderByColumn{
Column: clause.Column{Name: "transaction_date"},
Desc: DESCENDING,
}).
Count(&count).
Limit(PAGE_SIZE). // limit must come after count in order to get a total
Find(&ts)
Comment From: prazian
err := Dbo.Table("user").
In my case I cannot use the
Limit(-1)hack with Scopes, which make scopes and the advantages not useful for me anymore, which again is a pity.
err := models.DB. Preload("association"). Scopes(models.Paginate(c)). Find(&model). Limit(-1). Count(&count). ErrorAm I missing something in my case? 🤔
Today, I faced the same issue with pagination through Scopes and then wanting to reset (for counting) using .Limit(-1).Offset(-1).
Did you find any solution for it?
This is my code:
func CountResults(db *gorm.DB, model interface{}, scopes *[]DBScope) (int64, error) {
var count int64
res := db.Model(model)
if scopes != nil {
for _, scope := range *scopes {
res = res.Scopes(scope)
}
}
// Reset limit and offset to count everything <- this doesn't work as expected!
res.Limit(-1).Offset(-1)
res.Count(&count)
if res.Error != nil {
return 0, res.Error
}
return count, nil
}
But the final query still has the limit and offset!
Comment From: fernandofleury
@prazian I've completely decoupled the pagination from the scope usage to "fix it":
func (p *Pagination[T]) Paginate(db *gorm.DB) *gorm.DB {
var total int64
db.Count(&total)
p.CountResults = int(total)
p.CountPages = p.SafePages(int(total), p.SafeLimit())
return db.Offset(p.Offset()).Limit(p.SafeLimit())
}
func (r *repo) SampleQuery(ctx context.Context, pagination *database.Pagination[SampleType]) (*database.Pagination[SampleType], error) {
var results []SampleType
query := repo.db.
WithContext(ctx).
// notice the Model being chained here even tho Find already has it. We need it since Find would only happen after counting
Model(&results).
// key point to notice here is that we count right before executing the query so it contains all the filters
if err := pagination.Paginate(query).Find(&results).Error; err != nil {
return nil, err
}
pagination.Results = results
return pagination, nil
}
Comment From: prazian
Thanks, @fernandofleury, for sharing. I also ended up taking a similar approach.