Как построить подзапрос в виде столбца SELECT * FROM (‹subquery›) ORDER BY;?

Я использую gorm для взаимодействия с базой данных postgres. Я пытаюсь ORDER BY запрос, который использует DISTINCT ON и этот вопрос документирует, как это не так просто сделать. Поэтому мне нужно получить запрос в виде

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

На первый взгляд кажется, что мне нужно использовать db.QueryExpr(), чтобы превратить мой запрос в выражение и построить вокруг него другой запрос. Однако не похоже, что у gorm есть простой способ напрямую указать предложение FROM. Я пытался использовать db.Model(expr) или db.Table(fmt.Sprint(expr)), но Модель, похоже, полностью игнорируется, а fmt.Sprint(expr) возвращает не совсем то, что я думал. Выражения содержат несколько частных переменных. Если бы я мог превратить исходный запрос в полностью проанализированную строку, я мог бы использовать db.Table(query), но я не уверен, что смогу сгенерировать запрос в виде строки, не запуская его.

Если у меня есть полностью построенный запрос gorm, как я могу обернуть его в другой запрос, чтобы выполнить ORDER BY, который я пытаюсь выполнить?


person Corey Ogburn    schedule 31.01.2018    source источник


Ответы (1)


Если вы хотите написать необработанный SQL (включая тот, который имеет подзапрос SQL), который будет выполняться, а результаты будут добавлены к объекту с помощью gorm, вы можете использовать методы .Raw() и .Scan():

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

Вы передаете ссылку указателя на объект в .Scan(), который структурирован как результирующие строки, очень похоже на то, как вы использовали бы .First(). .Raw() также может добавлять данные в запрос, используя ? в запросе и добавляя значения в виде разделенных запятыми входных данных для функции:

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

Для получения дополнительной информации о том, как использовать построитель SQL, .Raw() и .Scan(), взгляните на примеры в документации: http://gorm.io/advanced.html#sql-builder

person Jon Chan♦    schedule 02.02.2018