如何在Django的case语句中使用汇总

时间:2019-01-09 03:11:34

标签: django

我试图在Django的case语句中使用聚合列,但我没有运气让Django接受它。

该代码将返回一个玩过游戏的人,玩游戏的次数及其总分的列表。该列表按总分降序排列。但是,该游戏具有最少打法才能获得资格。没有足够打法的玩家列在底部。例如:

Player  Total  Plays
Jill      109     10
Sam        92     11
Jack       45      9
Sue        50      3

苏在列表中排名第四,因为她的出场次数(3)少于最小值(5)。

相关的模型和功能是:

class Player(models.Model):
    name = models.CharField()

class Game(models.Model):
    name = models.CharField()
    min_plays = models.IntegerField(default=1)

class Play(models.Model):
    game = models.ForeignKey(Game)

class Score(models.Model):
    play = models.ForeignKey(Play)
    player = models.ForeignKey(Player)
    score = models.IntegerField()

def game_standings(game):
    query = Player.objects.filter(score__play__game_id=game.id)
    query = query.annotate(plays=Count('score', filter=Q(score__play__game_id=self.id)))
    query = query.annotate(total_score=Sum('score', filter=Q(score__play__game_id=self.id)))
    query = query.annotate(sufficient=Case(When(plays__ge=game.minimum_plays, then=1), default=0)
    query = query.order_by('-sufficient', '-total_score', 'plays')

当单击最后一个注释方法时,将报告“ IntegerField不支持的查找'ge'或不允许在字段上加入”错误。我试图更改case语句以嵌入计数,而不是使用带注释的字段:

query = query.annotate(
    sufficient=Case(When(
        Q(Count('score', filter=Q(score__play__game_id=game.id)))> 3, then=1), default=0
    )
)

但是Django报告带有'>'以及Q和int的TypeError。

我试图获取的SQL是:

SELECT "player"."id",
       "player"."name",
       COUNT("score"."id") FILTER (WHERE "play"."game_id" = 8) AS "plays",
       SUM("score"."score") FILTER (WHERE "play"."game_id" = 8) AS "total_score",
       case when COUNT("score"."id") FILTER (WHERE "play"."game_id" = 8) >= 5 then 1
       else 0
       end as sufficient
FROM "player"
       LEFT OUTER JOIN "score" ON ("player"."id" = "score"."player_id")
       LEFT OUTER JOIN "play" ON ("score"."play_id" = "play"."id")
WHERE "play"."game_id" = 8
GROUP BY "player"."id"
ORDER BY sufficent desc, total_score desc

我似乎无法弄清楚如何使用case语句进行计数。

谢谢

0 个答案:

没有答案