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

Django ORM使用distinct去重时按created_at排序失效的解决方法咨询

问题根因

你当前的写法仅针对PostgreSQL数据库有效,逻辑是按lead_id分组去重时,每个lead_id保留created_at最新的一条记录,但最终返回结果的排序规则是优先按lead_id升序排序,同lead_id下才按created_at降序排序,不会全局按created_at排序,这就是你感觉排序逻辑不生效的核心原因。

替代解决方案

方案1:子查询二次查询(全数据库兼容)

先拿到去重后的记录ID集合,再对目标结果做全局排序:

# 第一步:查询每个lead_id对应最新记录的主键ID
distinct_record_ids = IncomingCallRecording.objects.order_by("lead_id", "-created_at").distinct("lead_id").values_list("id", flat=True)
# 第二步:过滤出目标记录后按created_at全局排序
sorted_result = IncomingCallRecording.objects.filter(id__in=distinct_record_ids).order_by("-created_at")

该方案兼容MySQL、PostgreSQL等所有Django支持的数据库,代码逻辑简单易维护。

方案2:窗口函数实现(单查询完成,PostgreSQL/MySQL 8.0+支持)

通过RowNumber窗口函数标记每个lead_id分组下的记录排序,过滤出第一条后直接全局排序:

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

sorted_result = IncomingCallRecording.objects.annotate(
    # 按lead_id分组,组内按created_at倒序编号
    row_num=Window(
        expression=RowNumber(),
        partition_by=F('lead_id'),
        order_by=F('created_at').desc()
    )
).filter(row_num=1).order_by('-created_at')

该方案仅需一次数据库查询,适合数据量较大、需要拼接复杂查询逻辑的场景。

内容的提问来源于stack exchange,提问作者Sidhar_t.py

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:15:02