Django ORM子查询结合Max函数报错求助(PostgreSQL 15)
解决方案
错误原因分析
你原来的代码生成的子查询会返回多行结果——因为你按sequence分组并计算Max("sequence"),这会让每个存在的sequence值都对应一条结果,而WHERE子句里的=操作符要求子查询只能返回单行,所以触发ProgrammingError。
方案一:修正子查询逻辑
直接针对每个declaration计算最大sequence,确保子查询仅返回单行结果:
from django.db.models import OuterRef, Subquery, Max # 子查询:获取当前Task对应的declaration的最大sequence值 max_seq_subquery = Task.objects.filter( declaration=OuterRef('declaration'), sequence__isnull=False ).values('declaration').annotate( max_seq=Max('sequence') ).values('max_seq') # 主查询:筛选sequence等于对应declaration最大sequence的Task qs = Task.objects.filter( sequence=Subquery(max_seq_subquery), sequence__isnull=False )
这段代码生成的SQL会直接对每个declaration分组取最大sequence,子查询仅返回单行,避免了多行错误。
方案二:使用窗口函数(更简洁)
利用PostgreSQL支持的窗口函数,按declaration分组后给每条记录按sequence降序排号,直接取排号为1的记录(即每个分组中sequence最大的行):
from django.db.models import Window, F from django.db.models.functions import RowNumber qs = Task.objects.filter( sequence__isnull=False ).annotate( row_num=Window( expression=RowNumber(), partition_by=F('declaration'), # 按declaration分组 order_by=F('sequence').desc() # 按sequence降序排序 ) ).filter(row_num=1)
这种方法无需子查询,逻辑更直观,还能处理同一个declaration下有多个Task拥有相同最大sequence的场景。
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

