使用Django queryset为每个组获取前n名记录

使用Django queryset为每个组获取前n名记录,django,django-orm,Django,Django Orm,我有一个如下表所示的模型 create table `mytable` ( `person` varchar(10), `groupname` int, `age` int ); 我想从每组中选出两个年龄最大的人。原始的SQL问题和答案在这里,有效的解决方案之一是 SELECT person, groupname, age FROM ( SELECT person, groupname, age,

我有一个如下表所示的模型

create table `mytable`
(
  `person` varchar(10),
  `groupname` int,
  `age` int
);
我想从每组中选出两个年龄最大的人。原始的SQL问题和答案在这里,有效的解决方案之一是

SELECT
    person,
    groupname,
    age
FROM
(
    SELECT
        person,
        groupname,
        age,
        @rn := IF(@prev = groupname, @rn + 1, 1) AS rn,
        @prev := groupname
    FROM mytable
    JOIN (SELECT @prev := NULL, @rn := 0) AS vars
    ORDER BY groupname, age DESC, person
) AS T1
WHERE rn <= 2
您也可以在这里检查SQL输出


我只是想知道如何在Django的视图中将此查询实现为queryset。

另一个具有类似输出的SQL将具有窗口函数,该函数使用特定组名内的行号注释每一行,然后在HAVING子句中过滤行号小于或等于2的行

在编写django时,您需要在第一个查询中计算行,并在第二个查询中过滤人员

下面的代码基于,但它实现了对每个组\u名称返回的行数的限制

从django.db.models导入F,When,Window 从django.db.models.functions导入行数 人员ID={ 主键 对于pk,Person.objects.annotate中的\u组中的\u no\u行 组中的行号=窗口 表达式=行数, 分区依据=[F'组名称'], order_by=['group_name',F'age'.desc',person'] .values\u列表'id','row\u no\u在\u组' 如果组中没有行
>>> Person.objects.order_by('group_name', '-age', 'person').values_list('group_name', 'age', 'person')
<QuerySet [(1, 19, 'Brian'), (1, 17, 'Brett'), (1, 14, 'Teresa'), (1, 13, 'Sydney'), (2, 20, 'Daniel'), (2, 18, 'Maureen'), (2, 14, 'Vincent'), (2, 12, 'Carlos'), (2, 11, 'Kathleen'), (2, 11, 'Sandra')]>
>>> filtered_persons.order_by('group_name', '-age', 'person').values_list('group_name', 'age', 'person')
<QuerySet [(1, 19, 'Brian'), (1, 17, 'Brett'), (2, 20, 'Daniel'), (2, 18, 'Maureen')]>