如何获取 order_by 之后结果在列表中的位置?
我正在尝试找到一种有效的方法来查找数据库中对象与其分数相关的排名。我天真的解决方案如下所示:
rank = 0
for q in Model.objects.all().order_by('score'):
if q.name == 'searching_for_this'
return rank
rank += 1
应该可以使用 order_by 让数据库进行过滤:
Model.objects.all().order_by('score').filter(name='searching_for_this')
但是没有' t 似乎是在过滤器之后检索 order_by 步骤索引的一种方法。
有更好的方法吗? (使用 python/django 和/或原始 SQL。)
我的下一个想法是在插入时预先计算排名,但这看起来很混乱。
I'm trying to find an efficient way to find the rank of an object in the database related to it's score. My naive solution looks like this:
rank = 0
for q in Model.objects.all().order_by('score'):
if q.name == 'searching_for_this'
return rank
rank += 1
It should be possible to get the database to do the filtering, using order_by:
Model.objects.all().order_by('score').filter(name='searching_for_this')
But there doesn't seem to be a way to retrieve the index for the order_by step after the filter.
Is there a better way to do this? (Using python/django and/or raw SQL.)
My next thought is to pre-compute ranks on insert but that seems messy.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为您无法使用 Django ORM 在一个数据库查询中完成此操作。但如果它不打扰你,我会在模型上创建一个自定义方法:
然后你可以在任何地方使用“排名”,就像它是一个普通字段一样:
编辑:这个答案来自 2010 年现在我会推荐卡尔的解决方案。
I don't think you can do this in one database query using Django ORM. But if it doesn't bothers you, I would create a custom method on a model:
You can then use "ranking" anywhere, as if it was a normal field:
Edit: This answer is from 2010. Nowadays I would recommend Carl's solution instead.
使用 Django 2.0 中的新窗口函数,您可以像这样写...
Using the new Window functions in Django 2.0 you could write it like this...
使用类似这样的内容:
如果频繁使用并影响性能,您可以预先计算排名并将其保存到模型中。
Use something like this:
You can pre-compute ranks and save it to Model if they are frequently used and affect the performance.
在具有符合标准的数据库引擎(PostgreSql、SQL Server、Oracle、DB2...)的“原始 SQL”中,您可以只使用 SQL 标准
RANK
函数 - 但这不受支持在流行但非标准的引擎中,例如 MySql 和 Sqlite,并且(也许正因为如此)Django 不会向应用程序“显示”此功能。In "raw SQL" with a standard-conforming database engine (PostgreSql, SQL Server, Oracle, DB2, ...), you can just use the SQL-standard
RANK
function -- but that's not supported in popular but non-standard engines such as MySql and Sqlite, and (perhaps because of that) Django does not "surface" this functionality to the application.