sql >> Database teknologi >  >> RDS >> PostgreSQL

Aggregerede funktioner er ikke tilladt i en rekursiv forespørgsel. Er der en alternativ måde at skrive denne forespørgsel på?

Det er ikke kønt, men jeg fandt en løsning:

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;

I den rekursive del af forespørgslen, i stedet for at kalde GROUP BY og beregning af avg(r.rank) , Jeg bruger en vinduesfunktion, der er partitioneret på de samme kolonner. Dette har samme effekt ved at beregne den gennemsnitlige rangering.

En ulempe er, at denne beregning sker flere gange end nødvendigt. Hvis vi kunne GROUP BY derefter avg(r.rank) , det ville være mere effektivt end avg(r.rank) derefter GROUP BY .

Da der nu er dubletter i resultatet af den indlejrede forespørgsel, bruger jeg DISTINCT for at filtrere disse fra, og derefter beregner den ydre forespørgsel en RANK() af alle atleter i hver category_id baseret på disse gennemsnit.

Jeg vil stadig gerne høre, om nogen kender til en bedre måde at gøre dette på. Tak



  1. MYSQL Vælg rækker, hvor dato er ældre end datetime

  2. genindlæs siden ved hjælp af ajax for at oprette en live chat

  3. Hvordan indstiller jeg ActiveRecord-forespørgselstimeout for mysql?

  4. Datasikkerhedsstyring