为了账号安全,请及时绑定邮箱和手机立即绑定

Golang SQL 表 JOIN 到切片字段

Golang SQL 表 JOIN 到切片字段

Go
慕运维8079593 2023-08-14 17:33:23
考虑下表CREATE TABLE foo (  id INT PRIMARY KEY)CREATE TABLE bar (  id INT PRIMARY KEY)CREATE TABLE foo_bar_members (  foo_id INT NOT NULL REFERENCES foo(id) ON DELETE CASCADE ON UPDATE CASCADE,  bar_id INT NOT NULL REFERENCES bar(id) ON DELETE CASCADE ON UPDATE CASCADE,  PRIMARY KEY (foo_id, bar_id))foo_bar_membersfoo是连接和的关系表bar。查看foo作为 的父级bar。我有以下 Go 结构:type Foo struct {  ID     int `db:"id"`  BarIDs []int}BarIDs是与bar.id此相关联的一部分。我想查询这样的事情:foofoo.idSELECT * FROM foo f INNER JOIN foo_bar_members fbm ON f.id = fbm.foo_id WHERE f.id = $1但这个查询只是一个例子。显然这不会扫描到Foo.BarIDs. 我总是可以做两个单独的查询,但我想知道是否有更好的方法。我正在使用sqlx。
查看完整描述

1 回答

?
慕哥6287543

TA贡献1831条经验 获得超10个赞

SQL,这里的左连接也将返回没有关联的 bar 的 foos。


select

    foo.id

    , array_agg(bar.id)

from foo

left join foo_bar_members m on m.foo_id = foo.id

where foo.id = $1

group by foo.id

如果您只关心有 bar 的 foo,那么实际上不需要连接。


select

    m.foo_id

    , array_agg(m.bar_id)

from foo_bar_members m

where m.foo_id = $1

group by m.foo_id

执行代码:


const sql = "<one of the queries from above>"


f := new(Foo)

if err := db.QueryRow(sql, 123).Scan(&f.ID, pq.Array(&f.BarIDs)); err != nil {

    return err

}

pq.Array是一个返回实现sql.Scanner和driver.Valuer接口的值的函数,并且该实现知道如何将 postgres 数组扫描到 go 切片中或将 go 切片转换为 postgres 数组。


我不熟悉,所以它本身可能提供了一些允许您扫描数组的功能,因此可能没有必要sqlx使用。pq.Array也许更了解的人最终会提供他们的解决方案版本。


查看完整回答
反对 回复 2023-08-14
  • 1 回答
  • 0 关注
  • 89 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信