如何为每个给定的外键列表获取 n 项?
Posted
技术标签:
【中文标题】如何为每个给定的外键列表获取 n 项?【英文标题】:How do I get n items for each of the given list of foreignkey? 【发布时间】:2018-07-31 22:10:48 【问题描述】:我正在尝试找出一种在尽可能短的时间内执行此查询的方法。
number_of_results = 25
results = []
foreign_keys = [1,2,3,4,5]
for key in foreign_keys():
results.append(Model.objects.filter(foreign_key=key)[:number_of_resutlts])
即使是单个查询集,也没关系。我想要完成的是减少数据库查询的数量。我的数据库是 PostgreSQL 10。
如何进一步简化这一点?
【问题讨论】:
.filter(foreign_key__in=[1,2,3,4,5])
呢?
@gogaz 为每个键返回n
结果吗?
__in 将为您提供所有具有 foreign_key 为 1,2,3,4,5 的模型对象
它的分组依据和限制结果集。我认为没有一个步骤可以通过 Django 实现这一目标。
@NihalSharma 原始 sql 怎么样?
【参考方案1】:
试试这个:
results.append(Model.objects.filter(foreign_key__in=key)[:number_of_resutlts])
【讨论】:
【参考方案2】:这是一个group by and select n
问题。
似乎没有单步操作可以通过 Django 实现这一点。但是,使用联合,我们可以通过单个查询来访问数据库以获取结果。联合内部有自己的成本 - 单独运行查询并选择不同的等。
一种方法是使用原始 sql:
objs = Model.objects.raw(
"""SELECT rank_filter.* FROM (SELECT model.*, rank()
OVER (PARTITION BY foreign_key_id ORDER BY created DESC)
FROM model WHERE foreign_key_id IN (1,2,3,4,5))
rank_filter WHERE RANK <= n""") # replace n with 25
for obj in objs:
# do something
【讨论】:
【参考方案3】:从 Django 1.11 开始,您可以在这种情况下使用 QuerySet 的union
方法:
qs = Model.objects.filter(foreign_key=foreign_keys[0])[:number_of_results]
for fk in foreign_keys[1:]:
qs = qs.union(Model.objects.filter(foreign_key=fk)[:number_of_results])
https://docs.djangoproject.com/en/1.11/ref/models/querysets/#union
【讨论】:
Union 会触发个别查询,不是吗? 不,它会生成一个查询。 是的,一个查询里面有多个联合。检查过了。以上是关于如何为每个给定的外键列表获取 n 项?的主要内容,如果未能解决你的问题,请参考以下文章
当主键列是mysql中不同表的外键时,如何将主键列更改为自动递增