PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Funkcje agregujące nie są dozwolone w zapytaniu rekurencyjnym. Czy istnieje alternatywny sposób napisania tego zapytania?

To nie jest ładne, ale znalazłem rozwiązanie:

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;

W rekurencyjnej części zapytania, zamiast wywoływania GROUP BY i obliczanie avg(r.rank) , używam funkcji okna podzielonej na te same kolumny. Ma to ten sam efekt przy obliczaniu średniej pozycji.

Jedną wadą jest to, że te obliczenia zdarzają się więcej razy, niż jest to konieczne. Gdybyśmy mogli GROUP BY następnie avg(r.rank) , co byłoby bardziej wydajne niż avg(r.rank) następnie GROUP BY .

Ponieważ w wyniku zagnieżdżonego zapytania są teraz duplikaty, używam DISTINCT aby je odfiltrować, a następnie zewnętrzne zapytanie oblicza RANK() wszystkich sportowców w każdym category_id na podstawie tych średnich.

Nadal chciałbym usłyszeć, czy ktoś zna lepszy sposób na zrobienie tego. Dzięki



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sortuj wartości NULL na końcu tabeli

  2. Jak naprawić make 'PHP' w Mac OS X (10.9.4)?

  3. Jak to_date() działa w PostgreSQL

  4. Docker czeka na uruchomienie postgresql

  5. PostgreSQL INSERT do tablicy wyliczeń