我正在尝试使用Django的ORM执行以下查询:
SELECT
id,
pn,
revision,
description
FROM (SELECT
id,
pn,
revision,
MAX(revision)
OVER (
PARTITION BY pn ) max_rev,
description
FROM table) maxarts
WHERE revision = max_rev
结果必须是一个查询集,我已经尝试了所有我知道的Window/OuterRef/Subquery的组合,但都没有成功。我必须使用原始查询吗?
提前谢谢你,马可
编辑#1:
我会试着解释得更好,我有一个模型,看起来像这样:
class Article(models.Model):
pn = models.CharField()
revision = models.CharField()
description = models.CharField()
class Meta:
unique_together = [("pn", "revision"), ]
数据类似于:
pn1 rev1 description
pn1 rev2 description
pn2 rev1 anotherdescription
pn1 rev3 description
pn2 rev2 anotherdescription
我需要一个只包含Max("revision")值的queryset,该值在每次用户对对象进行修改时都会递增。我希望现在这一点更清楚了。谢谢!
编辑#2
正如我所建议的,我正在写我已经尝试过的东西:
原始SQL使用第一条消息中编写的查询,仅选择id字段并将其作为id__in=ids传递给ORM。像地狱一样慢,无法使用。
声明了要用作筛选器的WIndow函数:
Article.objects.annotate(
max_rev=Window(expression=Max("revision"), partition_by=F("pn"))
).filter(revision=F("max_rev"))
但是Django抱怨我不能在where子句中使用窗口函数(这是正确的)。
然后,我尝试使用窗口作为子查询:
window_query = Article.objects.annotate(
max_rev=Window(expression=Max("revision"), partition_by=F("pn"))
)
result = Article.objects.filter(revision=Subquery(window_query))
我也尝试过使用OuterRef,使用max_rev注释作为连接,但没有成功。我没主意了!
发布于 2018-06-05 06:53:17
那么,每次对文章进行修订时,都会在表中创建一行?
如果是这样,您需要做的就是执行一个计数查询,该查询对所有行进行计数,并根据'pn‘字段对它们进行分组。如果你想使用Max
函数,那么我建议用IntegerField
或DecimalField
代替pn字段,而不是使用CharField
。尽管这取决于您的应用程序所在的位置,但这可能会相当困难。
from django.db.models import Count
Article.objects.values('pn').annotate(maxvalues=Count('pn'))
https://stackoverflow.com/questions/50689138
复制相似问题