【问题标题】:Django annotation is not working with order_byDjango 注释不适用于 order_by
【发布时间】:2018-01-31 06:14:29
【问题描述】:

我想获取 MyModel order_by('-end_date') 的最后 100 条记录,并对不同的获胜者类型进行 SUM 注释

MyModel.objects.all()[:100].order_by('-end_game_time').values('winner').annotate(total=Count('winner'))

结果查询如下,我没有预期的组

<QuerySet [{'winner': 3, 'total': 1}, {'winner': 15, 'total': 1}, 'total': 1}, {'winner': 3, 'total': 1}, {'winner': 5, 'total': 1}, {'winner': 15, 'total': 1}, {'winner': 5, 'total': 1}, {'winner': 3, 'total': 1}, '...(remaining elements truncated)...']>

生成的查询就像

SELECT "game_mymodel"."winner", COUNT("game_mymodel"."winner") AS "total" FROM "game_mymodel" GROUP BY "game_mymodel"."winner", "game_mymodel"."end_game_time" ORDER BY "game_mymodel"."end_game_time" DESC LIMIT 100

但是当我没有 order_by 时,结果与我预期的一样

MyModel.objects.all()[:100].values('winner').annotate(total=Count('winner'))
Out[52]: <QuerySet [{'winner': 5, 'total': 43}, {'winner': 1, 'total': 2}, {'winner': 15, 'total': 51}, {'winner': 2, 'total': 42}, {'winner': 3, 'total': 43}]>

和生成的查询group_by部分不同

SELECT "game_mymodel"."winner", COUNT("game_mymodel"."winner") AS "total" FROM "game_mymodel" GROUP BY "game_mymodel"."winner" LIMIT 100

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    据我所知,在单个查询中不可能实现您想要做的事情,您在 SQL 中想要的是:

    SELECT "game_mymodel"."winner", COUNT("game_mymodel"."winner") AS "total" FROM "game_mymodel" GROUP BY "game_mymodel"."winner" ORDER BY "game_mymodel"."end_game_time" DESC LIMIT 100
    

    这不是一个有效的 sql 查询,因此您需要有一个子查询来选择 100 个元素,然后对它们应用聚合。

    首先构建子查询:

    top_100_games = MyModel.objects.order_by('-end_game_time')[:100].only('id').all()
    

    然后在主查询中使用它:

    MyModel.objects.filter(id__in=top_100_games).values('winner').annotate(total=Count('winner'))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-06
      • 2021-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-18
      • 2021-11-15
      • 2014-08-31
      相关资源
      最近更新 更多