sql >> Base de Datos >  >> RDS >> PostgreSQL

Las funciones agregadas no están permitidas en una consulta recursiva. ¿Hay alguna forma alternativa de escribir esta consulta?

No es bonito, pero encontré una solución:

WITH RECURSIVE rankings(rankable_type, rankable_id, athlete, value, rank) AS (
  SELECT 'Sport', sport_id, athlete, seconds, RANK() over(PARTITION BY sport_id ORDER BY seconds)
  FROM lap_times lt

  UNION ALL

  SELECT 'Category', *, rank() OVER(PARTITION by category_id ORDER BY avg_rank) FROM (
    SELECT DISTINCT category_id, athlete, avg(r.rank) OVER (PARTITION by category_id, athlete) AS avg_rank
    FROM categories c
    JOIN memberships m ON m.category_id = c.id
    JOIN rankings r ON r.rankable_type = m.member_type AND r.rankable_id = m.member_id
  ) _
)
SELECT * FROM rankings;

En la parte recursiva de la consulta, en lugar de llamar a GROUP BY y calculando avg(r.rank) , utilizo una función de ventana dividida en las mismas columnas. Esto tiene el mismo efecto de calcular el rango promedio.

Una desventaja es que este cálculo ocurre más veces de las necesarias. Si pudiéramos GROUP BY entonces avg(r.rank) , eso sería más eficiente que avg(r.rank) luego GROUP BY .

Dado que ahora hay duplicados en el resultado de la consulta anidada, estoy usando DISTINCT para filtrarlos y luego la consulta externa calcula un RANK() de todos los atletas en cada category_id basado en estos promedios.

Todavía me gustaría saber si alguien sabe de una mejor manera de hacer esto. Gracias