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

Cara yang tepat untuk membubuhi keterangan bidang peringkat untuk kumpulan kueri

Sayangnya, ini bukan operasi yang mungkin karena (bagi saya) postgresql WHERE operasi (filter/kecualikan) mempersempit baris sebelum fungsi agregasi dapat bekerja pada baris tersebut.

Satu-satunya solusi yang saya temukan adalah menghitung peringkat untuk semua Person dengan queryset terpisah dan kemudian, untuk membubuhi keterangan queryset Anda dengan hasil ini.

Jawaban ini (lihat metode yang ditingkatkan) menjelaskan cara "menganotasi kumpulan kueri dengan data yang disiapkan secara eksternal dalam dict".

Inilah implementasi yang saya buat untuk model Anda:

class PersonQuerySet(models.QuerySet):
    def total_scores(self):
        # compute the global ranking
        ranks = (Person.objects
                 .annotate(total_score=models.Sum('session__gamesession__score'))
                 .annotate(rank=models.Window(expression=DenseRank(),
                                              order_by=models.F('total_score').decs()))
                 .values('pk', 'rank'))
        # extract and put ranks in a dict
        rank_dict = dict((e['pk'], e['rank']) for e in ranks)

        # create `WHEN` conditions for mapping filtered Persons to their Rank
        whens = [models.When(pk=pk, then=rank) for pk, rank in rank_dict.items()]
        # build the query
        return (self.annotate(rank=models.Case(*whens, default=0,
                                               output_field=models.IntegerField()))
                .annotate(total_score=models.Sum('session__gamesession__score')))

Saya mengujinya dengan Django 2.1.3 dan Postgresql 10.5, jadi kodenya mungkin sedikit berubah untuk Anda.
Jangan ragu untuk berbagi versi yang kompatibel dengan Django 1.11!




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hitung Kesenjangan yang Dikelompokkan Dalam Waktu Untuk Rentang Waktu

  2. FATAL:tidak dapat mengakses file kunci pribadi /etc/ssl/private/ssl-cert-snakeoil.key:Izin ditolak

  3. Membuat salinan database di PostgreSQL

  4. Postgres tatanan alam oleh

  5. mengapa executeUpdate mengembalikan 1 meskipun tidak ada baris baru yang dimasukkan?