我有一个PostgreSQLUPDATE
查询,它根据同一个表中每一行的ROW_NUMBER()
按另一个字段(rating
)排序,更新表中每一行的一个字段(global_ranking
)。此外,更新是分区的,因此每一行的排名仅与那些属于相同language
的行相关
简而言之,我正在更新游戏中每个玩家的排名,基于他们当前的评级
PostgreSQL查询如下所示:
UPDATE stats_userstats
SET
global_ranking = sub.row_number
FROM (
SELECT id, ROW_NUMBER() OVER (
PARTITION BY language
ORDER BY rating DESC
) AS row_number
FROM stats_userstats
) sub
WHERE stats_userstats.id = sub.id;
我也在使用Django,如果可能的话,学习如何使用Django ORM表达这个查询会很有趣
Django似乎拥有表达查询所需的一切,包括使用PostgreSQL的ROW_NUMBER()
窗口函数的能力,但我当前的尝试是使用1
更新所有行ranking
:
from django.db.models import F, OuterRef, Subquery
from django.db.models.expressions import Window
from django.db.models.functions import RowNumber
UserStats.objects.update(
global_ranking=Subquery(
UserStats.objects.filter(
id=OuterRef('id')
).annotate(
row_number=Window(
expression=RowNumber(),
partition_by=[F('language')],
order_by=F('rating').desc()
)
).values('row_number')
)
)
我使用from django.db import connection; print(connection.queries)
来查看由Django ORM语句生成的查询,并得到了这个模糊相似的SQL语句:
UPDATE "stats_userstats"
SET "global_ranking" = (
SELECT ROW_NUMBER() OVER (
PARTITION BY U0."language"
ORDER BY U0."rating" DESC
) AS "row_number"
FROM "stats_userstats" U0
WHERE U0."id" = "stats_userstats"."id"
看起来我需要做的是将子查询从查询的SET
部分移动到FROM
,但我不清楚如何重新构造Django ORM语句来实现这一点
非常感谢您的帮助,我会在游戏结束后留下评论,并附上游戏链接:)谢谢
目前没有回答
相关问题 更多 >
编程相关推荐