如何在Django中对Person模型执行去重查询获取唯一人员记录?
解决方案
首先明确:我们以first_name、last_name、sexe三个字段的组合作为判断“同一人员”的依据,以下提供两种常见实现方式:
方式一:获取唯一人员的基础信息(字典列表)
如果只需要人员的唯一标识信息(不需要完整的Person实例),可以直接用distinct()配合values():
Person.objects.values('first_name', 'last_name', 'sexe').distinct()
该语句会返回由first_name、last_name、sexe组合而成的唯一字典列表,不会包含重复的人员组合。
方式二:获取完整的唯一人员实例(保留一条记录)
如果需要获取完整的Person对象,通常会选择保留每个人员的最新/最早注册记录,这里以保留最新记录为例:
方法1:使用子查询(推荐)
from django.db.models import Subquery, OuterRef # 子查询:获取每个人员最新注册记录的ID latest_records = Person.objects.filter( first_name=OuterRef('first_name'), last_name=OuterRef('last_name'), sexe=OuterRef('sexe') ).order_by('-arrival_date', '-id')[:1] # 主查询:筛选出这些最新记录 unique_persons = Person.objects.filter(id__in=Subquery(latest_records))
这里额外加上-id排序是为了避免同一人员同一天有多条记录时出现重复,确保只取ID最大的那条。
方法2:使用聚合函数关联查询
from django.db.models import Max # 先聚合得到每个人员的最新注册日期 person_max_dates = Person.objects.values('first_name', 'last_name', 'sexe').annotate(latest_arrival=Max('arrival_date')) # 筛选出对应日期的记录 unique_persons = Person.objects.filter( first_name__in=[p['first_name'] for p in person_max_dates], last_name__in=[p['last_name'] for p in person_max_dates], sexe__in=[p['sexe'] for p in person_max_dates], arrival_date__in=[p['latest_arrival'] for p in person_max_dates] )
注意:如果同一人员在同一天有多个注册记录,这种方法会返回多条该人员的记录,需要额外处理(比如再按ID去重)。
内容的提问来源于stack exchange,提问作者Etsè FIATSI
相关产品推荐
相关产品推荐

