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
相关产品推荐
相关产品推荐

