简体   繁体   中英

How to chain joins in gorm?

I want to write a query like

SELECT table_a.*, table_c.* 
FROM table_a 
  LEFT JOIN table_b ON table_a.id = table_b.table_a_id
  LEFT JOIN table_c ON table_b.id = table_c.table_b_id
WHERE table_a.column_a = 'a_value',
  AND table_c.column_b = 'some_value'
  AND table_c.column_c = 'another_value';

EDIT: I missed out quite an important point in that the where clause variables are not fixed . Depending on input, there may be more or fewer columns used for each table.

Currently, my query looks like

db.Table("table_a").
    Joins("left join table_b on table_a.id = table_b.table_a_id").
    Joins("left join table_c on table_b.id = table_c.table_b_id").
    Select("table_a.*, table_c.*").
    Table("table_a").Where(map[string]interface{}{"column_a": "value"}).
    Table("table_c").Where(map[string]interface{}{
        "column_b": "some_value", 
        "column_c": "another_value",
    }).
    Find(&elem)

However, the logged SQL statement is

SELECT table_a.*, table_c.* 
FROM `table_c` # gorm gives the wrong starting table, should be table_a
  LEFT JOIN table_b ON table_a.id = table_b.table_a_id 
  LEFT JOIN table_c ON table_b.id = table_c.table_b_id 
WHERE (`table_c`.`column_a` = 'value') # wrong table again
  AND (`table_c`.`column_b` = 'some_value') 
  AND (`table_c`.`column_c` = 'another_value')

I'm not sure what's the issue here. Is it that simultaneous queries for different tables isn't possible with this syntax? I would prefer to avoid using the raw queries as much as possible.

UPDATE: I've tried dynamically generating the SQL where clause, but would prefer if there is a more straightforward way offered by gorm.

You don't need to call this many Table methods. It uses the last one that you've called to construct your SQL query.

Instead, once you have joined the tables, you can use them in the Where statements that come after the joins.

Try this:

db.Table("table_a").
    Joins("left join table_b on table_a.id = table_b.table_a_id").
    Joins("left join table_c on table_b.id = table_c.table_b_id").
    Select("table_a.*, table_c.*").
    Where("table_a.column_a = ?", "value").
    Where("table_c.column_b = ? AND table_c.column_c = ?", "some_value",  "another_value").
    Find(&elem)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM