Golang SQL таблица JOIN в поле слайса - PullRequest
0 голосов
/ 11 марта 2020

Рассмотрим следующие таблицы

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_members - это таблица отношений, которая связывает foo и bar. Просмотр foo как родителя bar. И у меня есть следующая Go struct:

type Foo struct {
  ID     int `db:"id"`
  BarIDs []int
}

BarIDs - это фрагмент bar.id, который связан с этим foo с помощью foo.id. Я хочу запросить что-то вроде этого:

SELECT * FROM foo f INNER JOIN foo_bar_members fbm ON f.id = fbm.foo_id WHERE f.id = $1

Но этот запрос является лишь примером. Очевидно, что это не будет сканироваться в Foo.BarIDs. Я всегда мог сделать два отдельных запроса, но мне интересно, есть ли лучшие способы. Я использую sqlx .

1 Ответ

1 голос
/ 11 марта 2020

SQL, левое соединение здесь также вернет 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

Если вы заботитесь только о 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

Код go:

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 - это функция, которая возвращает значение, реализующее * Интерфейсы 1014 * и driver.Valuer, и реализация знает, как сканировать массив postgres в срез go или превратить срез go в массив postgres.


I ' Я не знаком с sqlx, поэтому вполне возможно, что он сам предоставляет некоторую функцию, которая позволяет сканировать массивы, и поэтому использование pq.Array может быть ненужным. Может быть, кто-то, кто знает лучше, в конечном итоге предоставит свою версию решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...