Python Django:按每个不同列的最新值进行筛选
考虑到这个果篮模型 class FruitBasket(Model): fruit = CharField(max_length=128) count = PositiveIntegerField() 而这个样本数据, id fruit count ----- ---------- ----- 0 apple 10 1 banana 20 2 apple 5 3 banana 30 我想要一个django查询,返回以下项: [2,苹果,5,3,香蕉,30] 本质上,在本例中,我已经将时间戳简化为rowid,以获取每个水果的最新行 只有在使用postgres时才有效 仅在PostgreSQL上,可以在中传递位置参数*字段 以指定字段的名称,该字段应具有独立性 申请这将转换为SELECT DISTINCT ON SQL查询。这是我的建议 差别对于正常的不同调用,数据库会比较每个调用 确定哪些行不同时,每行中的字段。暂时 使用指定的字段名进行不同的调用,数据库将仅 比较指定的字段名 此外,您必须指定一个order_by,而不能指定时间戳:Python Django:按每个不同列的最新值进行筛选,python,sql,django,distinct,aggregate,Python,Sql,Django,Distinct,Aggregate,考虑到这个果篮模型 class FruitBasket(Model): fruit = CharField(max_length=128) count = PositiveIntegerField() 而这个样本数据, id fruit count ----- ---------- ----- 0 apple 10 1 banana 20 2 apple 5 3
q = FruitBasket.objects.distinct('fruit').order_by('fruit')
指定字段名时,必须在
QuerySet和order_by中的字段必须以中的字段开头
不同的,以相同的顺序
q = (
FruitBasket.objects
.values('id', 'fruit', 'count')
.distinct('fruit').order_by('-id')
)
例如,在a上选择DISTINCT将为每个选项提供第一行
a列中的值。如果你不指定订单,你会得到一些
任意行
但是,如果您可以通过在相同的顺序中使用相同的值来消除需求:distinct/order\u,那么值可能会更接近您
q = (
FruitBasket.objects
.values('id', 'fruit', 'count')
.distinct('fruit').order_by('-id')
)
现实地说,有时候打破ORM会更好
SELECT id, fruit, count
FROM FruitBasket
GROUP BY fruit
ORDER BY id DESC
所以这个查询不神奇
SELECT * FROM (SELECT id, fruit, count
FROM FruitBasket
ORDER BY id DESC) t
GROUP BY t.fruit
这个更好,但有点难看
您可以自己对此进行优化:
q = FruitBasket.objects.raw("""\
SELECT * FROM
(
SELECT id, fruit, count
FROM FruitBasket
ORDER BY id DESC
) t
GROUP BY t.fruit
""")
您可以尝试以下方法:
FruitBasket.objects.order_by('fruit', '-count').distinct('fruit')
在我的例子中,它适用于Django 2.1,作为一种替代方案,如果您固定了少量可能的不同值,您可以使用几个并非真正最优的查询,但应该适用于小型项目:
available_fruits = ['banana', 'apple'] # can be also an extra query to extract distinct values
fruits = [FruitBasket.objects.filter(fruit=x).latest('id') for x in available_fruits ]
在我的例子中,它只有4个值,所以我可以进行4个简单快速的查询。子查询可能会帮助您, 下面是一个例子:
似乎与之相关,我不确定你的意思是q=FruitBasket.objects.values'id',fruit',count',distinct'fruit.order_by'-id'应该有效,或者如果有效的话,它只是一个理想。没有。我可能只是重构以保留每个水果最新条目的外键。事实上,“水果”是我现实世界问题中的一个外键。我的意思是,如果它真的起作用,它将是理想的,唯一有效的解决方案是底部的那个。顶部解释了orm无法满足您需要的原因。如文档和其他答案中所述,这仅适用于PostgreSQL On PostgreSQL only,您可以传递位置参数*字段,以指定应应用DISTINCT的字段的名称
>>> from django.db.models import OuterRef, Subquery
>>> newest = Comment.objects.filter(post=OuterRef('pk')).order_by('-created_at')
>>> Post.objects.annotate(newest_commenter_email=Subquery(newest.values('email')[:1]))