sqlite 类似于Django表中的Counter

qjp7pelc  于 2023-06-23  发布在  SQLite
关注(0)|答案(2)|浏览(109)

我在sqlite3中有一个表,其中有一列告诉我游戏的获胜者:(计算机= 1,人类= 2,领带= 0)
模型(我正在开发django)是这样的,至少是必要的部分:

class GameWinners(models.Model):
    CHOICES = [(0, 'Draw'), (1, 'Computer'), (2, 'Human')]
    game_winner = models.IntegerField(choices=CHOICES)

我想得到一本字典,它能统计我每一个人获胜的次数或平局。类似于集合中的Counter:
games = {0: 27, 1: 125, 2: 170}
我知道我可以这样做:

tie = GameWinners.objects.filter(game_winner=0).count()
computer = GameWinners.objects.filter(game_winner=1).count()
human = GameWinners.objects.filter(game_winner=2).count()

games = {0: tie, 1: computer, 2: human}
但我想一定有更好的办法。

更新

虽然代码在我给出的示例中可以工作,但它必须过滤表三次才能计算不同的元素,将来它将是一个相当大的表。
在等待答案的同时,我也尝试过用(我认为这是我正在寻找的解决方案):

query = "SELECT COUNT(game_winner) FROM core_gamewinner GROUP_BY game_winner"
games = GameWinners.objects.raw(query)

正如@Tarquinius所建议的那样,这是一种更有效的方式。但它让我回到:

OperationalError at /
near "game_winner": syntax error
egdjgwm8

egdjgwm81#

从Django的Angular 来看,你可以做的改进并不多。您可以选择执行len(queryset)queryset.count()
文档中说,如果你只想得到计数,在查询集上使用方法count()是最有效的方法。然而,如果你还想从查询集中检索模型示例,你应该选择len(queryset),因为这不需要像.filter().count()那样进一步的数据库查找。
如果你喜欢一条线超过多条线,你可以去:

tie, computer, human = [GameWinners.objects.filter(game_winner=num).count() for num in (0,1,2)]

但我想这不是你问题的目的。
更多背景:最有效的调用应该是一个简单的SQL命令,对吧?这是由count()方法使用的,您可以在链接的文档中阅读。因此,由于count()SELECT COUNT(*)的 Package 器,因此使用和性能都非常直接。

1zmg4dgp

1zmg4dgp2#

最后我有一个错字,GROUP_BY => GROUP BY。我发现的最好的方法是这样的:

sql_query = "SELECT id, game_winner, count(game_winner) AS total FROM core_gamewinner GROUP BY game_winner"
rawquery = GameWinner.objects.raw(sql_query)
games = {_.game_winner: _.total for _ in rawquery}

相关问题