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

Správný způsob, jak anotovat pole hodnocení pro sadu dotazů

Bohužel to není možná operace, protože (pro mě) postgresql WHERE operace (filtrovat/vyloučit) zúží řádky předtím, než na nich mohou fungovat agregační funkce.

Jediné řešení, které jsem našel, je jednoduše vypočítat hodnocení pro všechny Person pomocí samostatné sady dotazů a poté anotaci sady dotazů s těmito výsledky.

Tato odpověď (viz vylepšená metoda) vysvětluje, jak „anotovat sadu dotazů externě připravenými daty v diktátu“.

Zde je implementace, kterou jsem vytvořil pro vaše modely:

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

Testoval jsem to s Django 2.1.3 a Postgresql 10.5, takže se vám kód může lehce změnit.
Neváhejte a sdílejte verzi kompatibilní s Django 1.11!




  1. Jaké jsou různé typy omezení dostupných v SQL Server - SQL Server / Výukový program T-SQL, část 50

  2. Datový typ ID uživatele Google OAuth 2.0 pro MYSQL

  3. Django:Chyba syntaxe MySQL při předávání parametrů do nezpracovaného SQL dotazu

  4. Chyby Postgres HStore – neznámý operátor