gpt4 book ai didi

Django QuerySet 二值子查询

转载 作者:行者123 更新时间:2023-12-03 16:40:50 26 4
gpt4 key购买 nike

给定一个模型

class Entity(models.Model):
identifier = models.IntegerField()
created = models.IntegerField()
content = models.IntegerField()

class Meta:
unique_together = (('identifier', 'created'))

我想用 created 查询所有对象在具有共同点的对象中最大 identifier .

在 SQL 中,子查询中的窗口函数解决了这个问题:
SELECT identifier, content
FROM entity
WHERE (identifier, created)
IN (SELECT identifier, max(created) OVER (PARTITION BY identifier)
FROM entity);

另见: http://sqlfiddle.com/#!17/c541f/1/0

窗口函数和子查询在 Django 2.0 中都可用。但是,我还没有找到用多列表达子查询表达式的方法。

有没有办法将该 SQL 查询转换为 Django QuerySet 世界?这可能是一个 XY 问题,我的问题可以用不同的方式解决吗?

我丑陋的解决方法是
Entity.objects.raw('''
SELECT * FROM app_entity e
WHERE e.created = (SELECT max(f.created) FROM app_entity f WHERE e.identifier = f.identifier)''')

因为底层的 sqlite3 版本显然无法处理多列子查询。

最佳答案

我认为你可以用另一种方式来做(但我不确定它是否会比窗口表达式表现得更好或更差)......

max_created = Entity.objects.filter(
identifier=OuterRef('identifier')
).order_by('-created').values('created')[:1]

Entity.objects.filter(
created=Subquery(max_created)
)

这个抢了最大的 created给定值 identifier ,作为相关子查询,然后只过滤那些匹配的。

这可能需要调整:我不确定您是否可以像这样过滤子查询,或者您是否需要 .annotate(max_created=Subquery(created)).filter(created=F('max_created'))或者其他类似的可怕的东西。

另外,如果你使用的是 postgres,你可以使用 DISTINCT ON获得一个非常简洁的解决方案的功能:
Entity.objects.order_by('identifier', '-created').distinct('identifier')

关于Django QuerySet 二值子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50407055/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com