Построение go-pg ORM-запроса для отношения многих ко многим

У меня есть 3 таблицы, чтобы представить мои отношения многие ко многим. клиенты, компании, компании, клиенты.

companies:
 - id
 - name

customers:
 - id
 - username

companies_customers:
 - id
 - customer_id
 - company_id

Теперь запрос, который я хочу выполнить, состоит в том, чтобы выбрать всех клиентов с идентификатором компании равным 1. Необработанный запрос SQL может / может выглядеть примерно так:

SELECT * FROM customers c INNER JOIN customers_companies cc ON c.id = cc.customer_id WHERE cc.company_id = 1

Я пытался сделать что-то вроде этого в go-pg:

var customers []*Customer

s.DB.Model(&customers).Relation("Companies", func(q *orm.Query) (*orm.Query, error) {
    return q.Where("company_id = ?", companyID), nil
}).Select()

1 ответ

Решение

В этом конкретном случае вы можете сделать обходной путь для выполнения этого конкретного запроса, я полагаю, у вас есть следующие структуры:

type Company struct {
    TableName struct{} `sql:"companies"`
    ID        int64
    Name      string
    Customers []*Customer `pg:",many2many:companies_customers"`
}

type Customer struct {
    TableName struct{} `sql:"customers"`
    ID        int64
    Username  string
    Companies []*Company `pg:",many2many:companies_customers"`
}

Если вам нужно только выполнить запрос с JOIN, ты можешь сделать

var customers []*Customer
err := conn.Model(&customers).Column("customer.*").Join("inner join companies_customers cc on customer.id = cc.customer_id").Where("cc.company_id = ?", companyID).Select()
if err != nil {
    // Error Handler
} else {
    for _, customer := range customers {
        fmt.Printf("Customer -> id: %d, username:%s \n", customer.ID, customer.Username)
    }
}

Это генерирует:

SELECT "customer".* FROM customers AS "customer" inner join companies_customers cc on customer.id = cc.customer_id WHERE (cc.company_id = 1)

Но вы также можете сделать следующее:

var customers []*Customer
var company Company
err = conn.Model(&company).Column("Customers").Where("company.id = ?", companyID).Select()
if err != nil {
    // error handler
} else {
    customers = company.Customers
    for _, customer := range company.Customers {
        fmt.Printf("Customer -> id: %d, username:%s \n", customer.ID, customer.Username)
    }
}

Этот код выполняет два запроса:

SELECT "company"."id", "company"."name" FROM companies AS "company" WHERE (company.id = 1)
SELECT companies_customers.*, "customer".* FROM customers AS "customer" JOIN companies_customers ON (companies_customers."company_id") IN ((1)) WHERE ("customer"."id" = companies_customers."customer_id")

Сначала создайте запрос для извлечения данных из companyпосле этого, приведите всех клиентов этой компании.

Другие вопросы по тегам