dongwei2882 2017-01-09 02:12
浏览 185
已采纳

建立多对多关系的go-pg ORM查询

I've got 3 tables to represent my many to many relationship. customers, companies, companies_customers.

companies:
 - id
 - name

customers:
 - id
 - username

companies_customers:
 - id
 - customer_id
 - company_id

Now the query I want to run is to select all the customers with a company_id of 1. A raw SQL query could/might look something like this:

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

I've tried doing something like this in 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条回答 默认 最新

  • dtcd27183 2017-01-09 04:01
    关注

    In this particular case, you can do some workaround to perform this specific query, I suppose you have theses structures:

    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"`
    }
    

    If you only need to perform the query with the JOIN, you can do

    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 
    ", customer.ID, customer.Username)
        }
    }
    

    This generate:

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

    But, you also can do the following:

    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 
    ", customer.ID, customer.Username)
        }
    }
    

    This code perform two queries:

    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")
    

    First create a query to fetch the data from company, after that, fetch all the customers for that company.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 AT89C51控制8位八段数码管显示时钟。
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题