PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Fungsi agregat tidak diperbolehkan dalam kueri rekursif. Apakah ada cara alternatif untuk menulis kueri ini?

Itu tidak cantik, tapi saya menemukan solusinya:

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;

Di bagian rekursif dari kueri, alih-alih memanggil GROUP BY dan menghitung avg(r.rank) , saya menggunakan fungsi jendela yang dipartisi pada kolom yang sama. Ini memiliki efek yang sama dalam menghitung peringkat rata-rata.

Satu kelemahannya adalah bahwa perhitungan ini terjadi lebih sering daripada yang diperlukan. Jika kita bisa GROUP BY lalu avg(r.rank) , itu akan lebih efisien daripada avg(r.rank) lalu GROUP BY .

Karena sekarang ada duplikat dalam hasil kueri bersarang, saya menggunakan DISTINCT untuk menyaring ini dan kemudian kueri luar menghitung RANK() dari semua atlet di setiap category_id berdasarkan rata-rata ini.

Saya masih ingin mendengar jika ada yang tahu cara yang lebih baik untuk melakukan ini. Terima kasih



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Arsip WAL:GAGAL (pastikan pengiriman WAL sudah diatur)

  2. Cara membuat daftar semua pengguna di PostgreSQL

  3. Bagaimana cara mencadangkan database postgresql dari dalam psql?

  4. Dengan sqlalchemy cara mengikat secara dinamis ke mesin database berdasarkan permintaan

  5. Kueri PostgreSQL tidak dimatikan saat server aplikasi dimatikan