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

如何使用Django ORM删除bad_reviews表中指定字段的重复记录?

用Django ORM重写多字段重复记录查询

你需要基于client_id、survey_id、text、rating、privacy_agreement字段找出BadReviews模型中的重复记录,对应你提供的SQL查询,用Django ORM可以这样实现:

1. 还原原SQL的查询逻辑(找出所有重复记录)

先构建子查询筛选出存在重复的字段组合,再关联原表获取所有重复记录:

from django.db.models import Count, Exists, OuterRef

# 第一步:找出存在重复的字段组合(对应SQL中的dupes子查询)
duplicate_groups = BadReviews.objects.values(
    'client_id', 'survey_id', 'text', 'rating', 'privacy_agreement'
).annotate(record_count=Count('id')).filter(record_count__gt=1)

# 第二步:筛选出所有属于重复组的记录,对应SQL的JOIN逻辑
duplicate_records = BadReviews.objects.filter(
    Exists(
        duplicate_groups.filter(
            client_id=OuterRef('client_id'),
            survey_id=OuterRef('survey_id'),
            text=OuterRef('text'),
            rating=OuterRef('rating'),
            privacy_agreement=OuterRef('privacy_agreement')
        )
    )
).order_by(
    'client_id', 'survey_id', 'text', 'rating', 'privacy_agreement', 'id'
)

这段ORM代码生成的SQL逻辑和你提供的完全一致:先通过分组统计找出有重复的字段组合,再通过关联筛选出所有属于这些组合的记录,最后按指定字段排序。

2. 扩展:删除重复记录(保留每组中ID最小的条目)

如果最终目的是删除重复记录,只保留每组中ID最小的那条,可以用以下代码:

from django.db.models import Min

# 获取每个重复组中需要保留的最小ID
keep_ids = BadReviews.objects.values(
    'client_id', 'survey_id', 'text', 'rating', 'privacy_agreement'
).annotate(min_record_id=Min('id')).values_list('min_record_id', flat=True)

# 删除所有不在保留ID列表中的重复记录
BadReviews.objects.exclude(id__in=keep_ids).delete()

代码说明

  • values()指定分组字段,和你SQL中的GROUP BY对应;
  • annotate(Count('id'))统计每组的记录数,对应SQL中的COUNT(*);
  • Exists()子查询实现了SQL中的JOIN关联逻辑,确保只匹配完全相同的字段组合;
  • order_by()和你原SQL的排序规则完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:11:19