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

Django中distinct去重后能否按字段排序?报错问题求助

问题解决:Django中distinct去重后排序的实现方法

为什么你的代码报错?

你遇到的ProgrammingError是PostgreSQL的语法限制导致的:DISTINCT ON要求SQL语句的ORDER BY必须以DISTINCT ON指定的字段(这里是sku_id)开头。你在distinct('sku_id')后调用order_by('id'),会直接覆盖之前的排序规则,最终的ORDER BY里没有sku_id,违反了PostgreSQL的要求。

可以实现去重后排序,两种可行方案:

方案1:内存中排序(适合数据量小的场景)

先执行去重查询,再将结果转为列表后用Python的sorted函数按id排序:

# 先按sku_id和id去重,得到每个sku_id对应最早(id最小)的记录
queryset = self.filter_queryset(queryset.order_by('sku_id', 'id').distinct('sku_id'))
# 在内存中按id排序
sorted_result = sorted(queryset, key=lambda item: item.id)

注意:这种方式会把所有去重后的记录加载到内存,数据量大时性能较差,且不适合配合分页使用。

方案2:数据库层面子查询排序(适合大数据量/分页场景)

通过子查询先筛选出每个sku_id对应的目标记录(比如id最小或最大的那条),再在外层查询中按id排序:

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

# 子查询:获取每个sku_id对应的最小id(如果要最新记录就用Max('id'))
subquery = MyModel.objects.filter(sku_id=OuterRef('sku_id')).values('sku_id').annotate(target_id=Min('id')).values('target_id')
# 筛选出目标记录并按id排序
queryset = self.filter_queryset(MyModel.objects.filter(id__in=Subquery(subquery)).order_by('id'))

这种方式完全在数据库层面执行,性能更优,且支持分页操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 02:52:05