问题
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?
回答1:
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
来源:https://stackoverflow.com/questions/48549855/how-to-construct-subquery-in-the-form-of-select-from-subquery-order-by-col