Postgresql + gorm 带组的复杂分页

Postgresql + gorm complex pagination with groups

我有 table GroupId 列,并且可能有大量行。有没有办法让数据按组分页?例如,获取前 10 组,然后获取下 10 组等?

Table 会有这种结构(默认情况下不排序)- 抱歉格式不正确,出于某种原因它不起作用,但我认为它是可见的

第 1 栏 第二栏 GroupId
数据A foo1 1
数据B foo2 1
数据C foo3 2

...

那么有没有一种方法可以有效地获取前 10 组的行,然后是接下来的 10 组等,而每组的行数不固定?假设有数百万行,组可以是任意数字。

它并没有真正分页,因为您只是通过有界标识符 (GroupId) 查询数据。如果您知道您的组 ID 并且它们是连续的,那么您可以这样做。这是使用纯 Go 完成的,您可以轻松地将 gorm 与此合并。

go playground

package main

import (
    "fmt"
)

func main() {
    for _, q := range queries() {
        fmt.Println(q)
    }
}

func queries() (out []string) {
    groups := []int{10, 20, 30, 40, 50, 60, 70, 80, 90, 100}
    for i := 0; i < len(groups); i++ {
        var lower, upper int = 0, 0
        if i != 0 {
            lower = groups[i-1]
        }
        upper = groups[i]
        q := fmt.Sprintf("SELECT * FROM MyTable WHERE GroupId >= %v AND GroupId < %v", lower, upper)
        out = append(out, q)
    }
    return
}

调用 queries 打印出每个应该 运行 的查询,得到每个组中的所有结果。例如:

SELECT * FROM MyTable WHERE GroupId >= 0 AND GroupId < 10
SELECT * FROM MyTable WHERE GroupId >= 10 AND GroupId < 20
SELECT * FROM MyTable WHERE GroupId >= 20 AND GroupId < 30
SELECT * FROM MyTable WHERE GroupId >= 30 AND GroupId < 40
SELECT * FROM MyTable WHERE GroupId >= 40 AND GroupId < 50
SELECT * FROM MyTable WHERE GroupId >= 50 AND GroupId < 60
SELECT * FROM MyTable WHERE GroupId >= 60 AND GroupId < 70
SELECT * FROM MyTable WHERE GroupId >= 70 AND GroupId < 80
SELECT * FROM MyTable WHERE GroupId >= 80 AND GroupId < 90
SELECT * FROM MyTable WHERE GroupId >= 90 AND GroupId < 100

到目前为止,我们假设您已经确切地知道要查询的内容 'group buckets'。相反,如果我们假设我们知道有多少个顺序组 (n) 以及每个查询需要多少个组(存储桶大小 s),我们可以轻松地创建一个函数来为我们提供存储桶我们应该查询。

go playground

func groups(n, s int) (out []int) {
    for i := 0; i <= n; i++ {
        if i == 0 {
            continue
        }
        if i%s == 0 || i == n {
            out = append(out, i)
        }
    }
    return
}