Convierta la consulta SQL en la relación ActiveRecord

¿Cómo puedo convertir la siguiente consulta SQL en una relación ActiveRecord para poder expandirla con ámbitos?

WITH joined_table AS (
    SELECT workout_sets.weight AS weight, 
        workouts.user_id AS user_id, 
        workouts.id AS workout_id, 
        workout_sets.id AS workout_set_id,
        workout_exercises.exercise_id AS exercise_id
    FROM workouts 
    INNER JOIN workout_exercises ON workout_exercises.workout_id = workouts.id 
    INNER JOIN workout_sets ON workout_sets.workout_exercise_id = workout_exercises.id       
    ORDER BY workout_sets.weight DESC
    ),

sub_query AS (
    SELECT p.user_id, MAX(weight) as weight
        FROM joined_table p
            GROUP BY p.user_id
),

result_set AS (
    SELECT MAX(x.workout_id) AS workout_id, x.user_id, x.weight, x.workout_set_id, x.exercise_id
    FROM joined_table x
    JOIN sub_query y 
    ON y.user_id = x.user_id AND y.weight = x.weight
    GROUP BY x.user_id, x.weight, x.workout_set_id, x.exercise_id
    ORDER BY x.weight DESC)

SELECT workouts.*, result_set.weight, result_set.workout_set_id, result_set.exercise_id
FROM workouts, result_set
WHERE workouts.id = result_set.workout_id 

¿Es esto algo que tendría que intentar con ARel directo?

He intentado dividirlo en ámbitos / subconsultas, pero las selecciones en las subconsultas terminan en la consulta adjunta, por lo que arrojan errores de PostgreSql porque la columna no está especificada en los BY de GRUPO u ORDER BY en la declaración de adjunto.

Actualizar: Tienes razón al suponer que es PostgreSql. Intenté tu consulta, pero arroja unPG::Error: ERROR: column "rownum" does not exist, tanto para la consulta directa como para la equivalencia de ActiveRecord.

Sin embargo, cuando envuelvo la consulta en una consulta separada, funciona. Supongo que ROW_NUMBER () no se creará hasta después de que la selección se proyecte en el conjunto de datos. Así que la siguiente consulta funciona:

SELECT workouts.*, t.weight, t.workout_set_id, t.exercise_id, t.row_num
FROM workouts,
(SELECT workouts.id as workout_id, workout_sets.weight as weight,
                workout_sets.id AS workout_set_id,
                   workout_exercises.id AS exercise_id,
                   ROW_NUMBER() OVER ( 
            PARTITION BY workouts.user_id 
            ORDER BY workout_sets.weight DESC, workouts.id DESC ) row_num
     FROM workouts
     JOIN workout_exercises ON workout_exercises.workout_id = workouts.id 
     JOIN workout_sets ON workout_sets.workout_exercise_id = workout_exercises.id) as t
WHERE workouts.id = t.workout_id AND t.row_num = 1

Que he logrado masajear en los siguientes:

  selected_fields = <<-SELECT
    workouts.id AS workout_id, 
    workout_sets.weight AS weight,
    workout_sets.id AS workout_set_id,
    workout_exercises.id AS exercise_id,
    ROW_NUMBER() OVER (
       PARTITION BY workouts.user_id 
       ORDER BY workout_sets.weight DESC, workouts.id DESC) as row_num
  SELECT

  Workout.joins(", (#{Workout.joins(:workout_exercises => :workout_sets).select(selected_fields).to_sql}) as t").select("workouts.*, t.*").where("workouts.id = t.workout_id AND t.row_num = 1").order("t.weight DESC")

Pero como puedes ver, eso es extremadamente intrépido y es un olor a código masivo. ¿Alguna idea de cómo refactorizar eso?

Respuestas a la pregunta(1)

Su respuesta a la pregunta