sql >> データベース >  >> RDS >> PostgreSQL

クエリセットのランクフィールドに注釈を付ける適切な方法

    残念ながら、(私にとっては)postgresql WHEREなので、これは可能な操作ではありません。 操作(フィルター/除外)は、集計関数が行を処理する前に行を絞り込みます。

    私が見つけた唯一の解決策は、すべてのPersonのランキングを単純に計算することです。 別のクエリセットを使用してから、これらの結果でクエリセットに注釈を付けます。

    この回答 (改善された方法を参照)「dictで外部的に準備されたデータでクエリセットに注釈を付ける」方法を説明します。

    これが私があなたのモデルのために作った実装です:

    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')))
    

    Django2.1.3とPostgresql10.5でテストしたので、コードが少し変わる可能性があります。
    Django 1.11と互換性のあるバージョンを自由に共有してください!




    1. メタデータ検出ウィザードの使用

    2. Hibernate 4.3.5 は v$session.program 構成プロパティを無視します

    3. XXXによる並べ替えASCまたはDESCによる並べ替え、動的な順序付け、mysql ..

    4. SQLServer2008のLPAD