英文:
GORM return list of list of results or map of results with group by id
问题
基本上,使用GORMDB,我的当前代码看起来像这样:
res := []*modelExample{}
DB.Model(&modelExample{}).
Order("task_id").
Find(&res)
然后,我会手动循环遍历res,并将具有相同task_id的模型追加到一个列表中,然后将此列表追加到要处理的列表中。我之所以需要这样做,是因为我需要对特定列进行一些特定操作,而这些操作无法在GORM中完成。
然而,有没有一种更高效的方法可以返回一个列表的列表,然后我可以使用for循环在每个列表元素上执行操作呢?
英文:
Essentially, using GORMDB, my current code looks something like this:
res = []*modelExample
DB.Model(&modelExample{}).
Order("task_id ").
Find(res)
And what I do with res is that I will manually loop through and append the models with the same task_id into one list, and then append this list to be worked on. The reason why I need to do this is because there are some specific operations i need to do on specific columns that I need to extract which I can't do in GORM.
However, is there a way to do this more efficiently where I return like a list of list, which I can then for loop and do my operation on each list element?
答案1
得分: 0
你可以使用以下代码片段来满足你的需求:
package main
import (
"fmt"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type modelExample struct {
TaskId int
Name string
}
func main() {
dsn := "host=localhost user=postgres password=postgres dbname=postgres port=5432 sslmode=disable"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
db.AutoMigrate(&modelExample{})
// 这里你需要使用一些数据来填充数据库
// 查询
res := make(map[int][]modelExample, 0)
rows, err := db.Table("model_examples").Select("task_id, name").Rows()
if err != nil {
panic(err)
}
defer rows.Close()
// 扫描
for rows.Next() {
var taskId int
var name string
rows.Scan(&taskId, &name)
if _, isFound := res[taskId]; !isFound {
res[taskId] = []modelExample{{taskId, name}}
continue
}
res[taskId] = append(res[taskId], modelExample{taskId, name})
}
// 扫描时始终检查错误是个好习惯
if err = rows.Err(); err != nil {
panic(err)
}
for _, v := range res {
fmt.Println(v)
}
}
在完成初始设置后,让我们仔细看一下查询部分。
首先,你将从表中获取所有记录。获取到的记录将存储在rows
变量中。
在for
循环中,你将扫描所有记录。每条记录将被添加为一个新的映射条目,或者追加到现有条目中(如果taskId
已经存在于映射中)。
这是根据特定列(例如TaskId
)创建不同列表的最简单方法。实际上,从我理解的情况来看,你需要拆分记录而不是使用聚合函数(例如COUNT
、SUM
等)对它们进行分组。
我添加的其他代码只是为了清晰起见。
如果这解决了你的问题,或者你需要其他帮助,请告诉我,谢谢!
英文:
You should be able to achieve your needs with the following code snippet:
package main
import (
"fmt"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type modelExample struct {
TaskId int
Name string
}
func main() {
dsn := "host=localhost user=postgres password=postgres dbname=postgres port=5432 sslmode=disable"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
db.AutoMigrate(&modelExample{})
// here you should populate the database with some data
// querying
res := make(map[int][]modelExample, 0)
rows, err := db.Table("model_examples").Select("task_id, name").Rows()
if err != nil {
panic(err)
}
defer rows.Close()
// scanning
for rows.Next() {
var taskId int
var name string
rows.Scan(&taskId, &name)
if _, isFound := res[taskId]; !isFound {
res[taskId] = []modelExample{{taskId, name}}
continue
}
res[taskId] = append(res[taskId], modelExample{taskId, name})
}
// always good idea to check for errors when scanning
if err = rows.Err(); err != nil {
panic(err)
}
for _, v := range res {
fmt.Println(v)
}
}
After the initial setup, let's take a closer look at the querying section.
First, you're going to get all the records from the table. The records you get are stored in the rows
variable.
In the for
loop, you scan all of the records. Each record will be either added as a new map entry or appended to an existing one (if the taskId
is already present in the map).
This is the easiest way to create different lists based on a specific column (e.g. the TaskId
). Actually, from what I understood, you need to split the records rather than grouping them with an aggregation function (e.g. COUNT
, SUM
, and so on).
The other code I added was just put in for clarity.
Let me know if this solves your issue or if you need something else, thanks!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论