PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Funções agregadas não são permitidas em uma consulta recursiva. Existe uma maneira alternativa de escrever esta consulta?


Não é bonito, mas encontrei uma solução:
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;

Na parte recursiva da consulta, em vez de chamar GROUP BY e calculando avg(r.rank) , eu uso uma função de janela particionada nas mesmas colunas. Isso tem o mesmo efeito de calcular a classificação média.

Uma desvantagem é que esse cálculo acontece mais vezes do que o necessário. Se pudéssemos GROUP BY então avg(r.rank) , isso seria mais eficiente que avg(r.rank) então GROUP BY .

Como agora há duplicatas no resultado da consulta aninhada, estou usando DISTINCT para filtrá-los e, em seguida, a consulta externa calcula um RANK() de todos os atletas em cada category_id com base nessas médias.

Eu ainda gostaria de saber se alguém conhece uma maneira melhor de fazer isso. Obrigado