sql >> Databáze >  >> RDS >> PostgreSQL

Agregační funkce nejsou v rekurzivním dotazu povoleny. Existuje alternativní způsob, jak napsat tento dotaz?

Není to hezké, ale našel jsem řešení:

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;

V rekurzivní části dotazu namísto volání GROUP BY a výpočet avg(r.rank) , používám funkci okna rozdělenou na stejné sloupce. To má stejný účinek jako výpočet průměrného hodnocení.

Nevýhodou je, že tento výpočet probíhá vícekrát, než je nutné. Kdybychom mohli GROUP BY pak avg(r.rank) , to by bylo efektivnější než avg(r.rank) pak GROUP BY .

Protože jsou nyní ve výsledku vnořeného dotazu duplikáty, používám DISTINCT odfiltrovat je a pak vnější dotaz vypočítá RANK() všech sportovců v každém category_id na základě těchto průměrů.

Stále bych byl rád, kdyby někdo věděl o lepším způsobu, jak to udělat. Díky



  1. Proč `libpq` pro načítání dat používá dotazování místo upozornění?

  2. Explicitně nastavte datový typ buňky jako text pro číselné hodnoty

  3. Seřaďte podle kontingenční tabulky created_at v Laravel

  4. Jak odstranit sloupec v SQL