Django 查询删除按 id 分组的旧值?

Django query to remove older values grouped by id?

我试图从 table 中删除按最旧时间戳具有重复值的记录,按 ID 分组,因此结果将是每个 ID 的唯一值和每个 ID/timestamp 保留,希望下面的示例有意义。

示例数据:

id     value    timestamp
10     10       9/4/20 17:00
11     17       9/4/20 17:00
21     50       9/4/20 17:00
10     10       9/4/20 16:00
10     10       9/4/20 15:00
10     11       9/4/20 14:00
11     41       9/4/20 16:00
11     41       9/4/20 15:00
21     50       9/4/20 16:00

所以 id 喜欢删除具有相同 id 的重复值的任何值,保留最新的时间戳,因此上述数据将变为:

id     value    timestamp
10     10       9/4/20 17:00
11     17       9/4/20 17:00
21     50       9/4/20 17:00
10     11       9/4/20 14:00
11     41       9/4/20 16:00

编辑:

查询只是

SampleData.objects.all()

一种方法是使用 Subquery 表达式,如 here 所述。

假设您的 SampleData 模型如下所示:

class SampleData(models.Model):

    id2 = models.IntegerField()
    value = models.IntegerField()
    timestamp = models.DateTimeField()

(为了避免和型号id冲突,我把id换成了id2)

然后您可以像这样删除重复项:

newest = SampleData.objects.filter(id2=OuterRef('id2'), value=OuterRef('value')).order_by('-timestamp')
SampleData.objects.annotate(newest_id=Subquery(newest.values('pk')[:1])).exclude(pk=F('newest_id')).delete()

编辑:

似乎 MySQL 在处理删除和子查询时遇到了一些问题,如 this SO post.

中所述

在这种情况下,分两步的方法应该会有所帮助:首先获取要删除的对象的 ID,然后删除它们:

 newest = SampleData.objects.filter(id2=OuterRef('id2'), value=OuterRef('value')).order_by('-timestamp')
 ids2delete = list(SampleData.objects.annotate(newest_id=Subquery(newest.values('pk')[:1])).exclude(pk=F('newest_id')).values_list('pk', flat=True))
 SampleData.objects.filter(pk__in=ids2delete).delete()