在 Django 查询中使用 .extra(select={...}) 引入的值上使用 .aggregate() ?
我试图像这样获取玩家每周玩的次数:
player.game_objects.extra(
select={'week': 'WEEK(`games_game`.`date`)'}
).aggregate(count=Count('week'))
但是 Django 抱怨
FieldError: Cannot resolve keyword 'week' into field. Choices are: <lists model fields>
我可以像这样用原始 SQL 来完成此操作
SELECT WEEK(date) as week, COUNT(WEEK(date)) as count FROM games_game
WHERE player_id = 3
GROUP BY week
有没有一个好的方法可以在 Django 中执行原始 SQL 而不执行此操作?
I'm trying to get the count of the number of times a player played each week like this:
player.game_objects.extra(
select={'week': 'WEEK(`games_game`.`date`)'}
).aggregate(count=Count('week'))
But Django complains that
FieldError: Cannot resolve keyword 'week' into field. Choices are: <lists model fields>
I can do it in raw SQL like this
SELECT WEEK(date) as week, COUNT(WEEK(date)) as count FROM games_game
WHERE player_id = 3
GROUP BY week
Is there a good way to do this without executing raw SQL in Django?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用自定义聚合函数来生成查询:
但是由于此 API 没有文档记录并且已经需要一些原始 SQL,因此您最好使用 原始查询。
You could use a custom aggregate function to produce your query:
But as this API is undocumented and already requires bits of raw SQL, you might be better off using a raw query.
这是问题的示例和不理想的解决方案。以这个示例模型为例:
这个示例聚合查询以与您的相同的方式失败,因为它尝试引用使用
.extra()
创建的非字段值。一个解决方案
可以通过在额外值的定义中使用聚合数据库函数(在本例中为 Avg)直接找到所需的值:
此查询将生成以下 SQL 查询:
尽管此中存在不需要的列查询,我们仍然可以通过隔离
percent_positive
值从中获取所需的值:Here is an example of the problem and an unideal workaround solution. Take this example model:
This example aggregate query fails in the same way as yours because it attempts to reference a non-field value created using
.extra()
.One Workaround Solution
The desired value can be found directly by using the aggregate database function (Avg in this case) within the extra value's definition:
This query will generate the following SQL query:
Despite the unneeded columns in this query, we can still obtain the desired value from it by isolating the
percent_positive
value: