You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中按非唯一字段获取指定sku的最新去重记录?

解决Django中获取每个SKU最新描述的问题

问题背景

给定模型:

class Item(models.Model):
    sku = models.CharField(null=False)
    description = models.CharField(null=True)

需要从指定SKU列表中,获取每个SKU对应**id最大(最新)**记录的描述。

原写法的问题

你之前的代码中Latest聚合的调用方式有误,正确的Latest需要明确指定排序字段作为参数,而非在后面链式调用order_by,且这种方式在处理可空字段时可能存在异常,因此更推荐以下两种可靠方案。

方案一:子查询获取最大ID关联查询

通过子查询先拿到每个SKU的最大ID,再关联到对应的记录:

from django.db.models import OuterRef, Subquery, Max

# 子查询:获取每个sku的最大id
max_id_subquery = Item.objects.filter(sku=OuterRef('sku')).values('sku').annotate(max_id=Max('id')).values('max_id')

# 过滤出所有sku在目标列表中,且id为对应sku最大id的记录
latest_items = Item.objects.filter(
    id__in=Subquery(max_id_subquery),
    sku__in=list_of_skus
)

# 转换为sku到描述的字典,方便使用
sku_latest_descr = {item.sku: item.description for item in latest_items}

方案二:使用Window函数排名筛选

利用Window函数给每个SKU的记录按id倒序排名,取排名第一的记录:

from django.db.models import Window, F
from django.db.models.functions import Rank

# 给每个sku的记录按id降序排名
ranked_items = Item.objects.filter(sku__in=list_of_skus).annotate(
    rank=Window(
        expression=Rank(),
        partition_by=F('sku'),
        order_by=F('id').desc()
    )
).filter(rank=1)

# 转换为sku到描述的字典
sku_latest_descr = {item.sku: item.description for item in ranked_items}

补充说明

如果一定要使用Latest聚合,正确的写法应该是:

from django.db.models import Latest

latest_skus = Item.objects.values('sku').filter(sku__in=list_of_skus).annotate(
    latest_descr=Latest('description', order_by='-id')
).values('sku', 'latest_descr')

但这种方式在description存在空值时,可能无法正确返回预期结果,因此更推荐前两种方案。

内容的提问来源于stack exchange,提问作者dekomote

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:55:23