Django如何对Drugs模型按location、num分组取最大date对应的记录
Django 多字段分组取每组最新记录实现方案
你需要实现的是按location和num联合分组,取每组date最大值对应的记录,可通过以下两种Django ORM方式实现:
方案1:窗口函数实现(推荐,适配Django 2.0及以上版本)
该方案执行效率高,单次查询即可得到结果:
from django.db.models import F, Window from django.db.models.functions import RowNumber latest_drugs = Drugs.objects.annotate( # 按location、num分组,组内按date倒序排序,给每条记录分配组内排名 row_num=Window( expression=RowNumber(), partition_by=[F('location'), F('num')], order_by=F('date').desc() ) # 过滤取每组排名第一的记录,即为该组最新记录 ).filter(row_num=1)
方案2:子查询实现(兼容低版本Django)
如果使用的Django版本不支持窗口函数,可使用子查询方式实现:
from django.db.models import Max, OuterRef, Subquery # 子查询:查询每个location+num分组对应的最大date max_date_subq = Drugs.objects.filter( location=OuterRef('location'), num=OuterRef('num') ).order_by().values('location', 'num').annotate( max_date=Max('date') ).values('max_date') # 主查询:匹配每条记录和对应分组的最大date,过滤得到目标记录 latest_drugs = Drugs.objects.filter( date=Subquery(max_date_subq) )
注意事项
- 针对你给出的测试数据,上述两种方案都会正确返回id为2、3的两条目标记录
- 如果同一分组下存在多条
date完全相同的记录,两种方法默认都会返回该分组下所有符合最大日期的记录。如果需要仅返回一条,可在排序规则中追加id倒序等唯一字段规则,保证分组内排序唯一 - 两种方案均兼容PostgreSQL、MySQL、SQLite等主流Django支持的数据库
内容的提问来源于stack exchange,提问作者Mereva
相关产品推荐
相关产品推荐

