Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django:按每个不同列的最新值进行筛选_Python_Sql_Django_Distinct_Aggregate - Fatal编程技术网

Python Django:按每个不同列的最新值进行筛选

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

考虑到这个果篮模型

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,而不能指定时间戳:

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]))