1

I am using gorm to interact with a postgres database. I'm trying to ORDER BY a query that uses DISTINCT ON and this question documents how it's not that easy to do that. So I need to end up with a query in the form of

 SELECT * FROM (<subquery>) ORDER BY column;

At first glance it looks like I need to use db.QueryExpr() to turn the query I have into an expression and build another query around it. However it doesn't seem gorm has an easy way to directly specify the FROM clause. I tried using db.Model(expr) or db.Table(fmt.Sprint(expr)) but Model seems to be completely ignored and fmt.Sprint(expr) doesn't return exactly what I thought. Expressions contain a few private variables. If I could turn the original query into a completely parsed string then I could use db.Table(query) but I'm not sure if I can generate the query as a string without running it.

If I have a fully built gorm query, how can I wrap it in another query to do the ORDER BY I'm trying to do?

Corey Ogburn
  • 24,072
  • 31
  • 113
  • 188

1 Answers1

0

If you want to write raw SQL (including one that has a SQL subquery) that will be executed and the results added to an object using gorm, you can use the .Raw() and .Scan() methods:

query := `
    SELECT sub.*
    FROM (<subquery>) sub
    ORDER BY sub.column;`
db.Raw(query).Scan(&result)

You pass a pointer reference to an object to .Scan() that is structured like the resulting rows, very similarly to how you would use .First(). .Raw() can also have data added to the query using ? in the query and adding the values as comma separated inputs to the function:

query := `
    SELECT sub.*
    FROM (<subquery>) sub
    WHERE
        sub.column1 = ?
        AND sub.column2 = ?
    ORDER BY sub.column;`
db.Raw(query, val1, val2).Scan(&result)

For more information on how to use the SQL builder, .Raw(), and .Scan() take a look at the examples in the documentation: http://gorm.io/advanced.html#sql-builder

Jon Chan
  • 969
  • 2
  • 12
  • 22