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

Django filter查询获取每位员工最新记录的实现方法

问题描述

我有一张名为employee的员工数据表,表结构与存量数据如下:

Employee表现有数据:

empid  name   status      created_datetime
EMP001 NAMEA  STATUS-B    2022-06-13 14:00:00
EMP001 NAMEA  STATUS-A    2022-06-13 13:00:00
EMP002 NAMEB  STATUS-B    2022-06-13 12:00:00
EMP003 NAMEC  STATUS-A    2022-06-13 11:30:00
EMP001 NAMEA  STATUS-C    2022-06-13 11:00:00
EMP001 NAMEA  STATUS-D    2022-06-13 10:00:00
EMP003 NAMEC  STATUS-B    2022-06-13 09:00:00

需要查询获取每位员工对应的最新一条记录,预期返回结果如下:

empid  name   status      created_datetime
EMP001 NAMEA  STATUS-B    2022-06-13 14:00:00
EMP002 NAMEB  STATUS-B    2022-06-13 12:00:00
EMP003 NAMEC  STATUS-A    2022-06-13 11:30:00

即返回每个empid对应的created_datetime值最大的记录,要求使用Django filter相关语法实现。

实现方案

首先假设Employee模型定义如下:

from django.db import models

class Employee(models.Model):
    empid = models.CharField(max_length=20, verbose_name="员工ID")
    name = models.CharField(max_length=50, verbose_name="员工姓名")
    status = models.CharField(max_length=20, verbose_name="员工状态")
    created_datetime = models.DateTimeField(verbose_name="记录创建时间")

方法1:子查询匹配(兼容所有数据库版本)

先分组查询每个员工ID对应的最新记录创建时间,再通过组合条件过滤出匹配的记录:

from django.db.models import Max, Q

# 查出每个empid对应的最新创建时间
emp_latest_time = Employee.objects.values('empid').annotate(
    latest_time=Max('created_datetime')
)

# 构造匹配条件
query_filter = Q()
for item in emp_latest_time:
    query_filter |= Q(
        empid=item['empid'],
        created_datetime=item['latest_time']
    )

# 拿到最终结果
result = Employee.objects.filter(query_filter)

方法2:窗口函数查询(Django 2.0+,数据库支持窗口函数时推荐,效率更高)

通过窗口函数给同个员工的记录按创建时间倒序编号,过滤出编号为1的记录即为每个员工的最新数据:

from django.db.models import Window, F
from django.db.models.functions import RowNumber

result = Employee.objects.annotate(
    row_rank=Window(
        expression=RowNumber(),
        partition_by=F('empid'),
        order_by=F('created_datetime').desc()
    )
).filter(row_rank=1)

注意事项

  • 如果存在同个员工同一created_datetime下有多条记录的场景,两种方法都会返回这些重复记录,可以根据业务规则追加过滤条件,比如额外匹配最大主键值去重。
  • 窗口函数方案要求数据库版本支持窗口特性:MySQL 8.0+、PostgreSQL 8.4+、SQLite 3.25+均可正常使用,如果是MySQL 5.x等不支持窗口函数的版本,使用方法1即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 23:12:24