django - 选择具有最大字段/列值的实例/行,每个字段/列(分组依据)
问题描述
所以,我有这些模型:
class Computer(models.Model):
hostname = models.CharField(primary_key=True, max_length=6)
<other computer info fields>
class ComputerRecord(models.Model):
id = models.AutoField(primary_key=True)
pc = models.ForeignKey(Computer, on_delete=models.CASCADE)
ts = models.DateTimeField(blank=False)
<other computerrecord info fields>
我想获取ts
每个pc
(计算机模型)具有最大值的行/计算机记录实例
在 sql 中会是这样的:
SELECT hub_computerrecord.*
FROM hub_computerrecord
JOIN (
SELECT pc_id, MAX(ts) AS max_ts
FROM hub_computerrecord
GROUP BY pc_id
) AS maxs ON hub_computerrecord.pc_id = maxs.pc_id
WHERE hub_computerrecord.ts = maxs.max_ts;
注意(编辑):有很多ComputerRecord
实例(10000+)所以任何效率太低的东西都行不通
解决方案
尝试这个
from django.db.models import Max, F
qs = ComputerRecord.objects.annotate(
max=Max('pc__computerrecord__ts')
).filter(
ts=F('max')
)
是的,这个表单表达式不会在 OP 中构建精确的SQL 查询,但它会产生相同的结果(可能存在一些性能问题,不确定矩阵)
raw()
或者,您可以使用以下方法执行原始 SQL
raw_query = """
SELECT hub_computerrecord.*
FROM hub_computerrecord
JOIN (
SELECT pc_id, MAX(ts) AS max_ts
FROM hub_computerrecord
GROUP BY pc_id
) AS maxs ON hub_computerrecord.pc_id = maxs.pc_id
WHERE hub_computerrecord.ts = maxs.max_ts;
"""
qs = ComputerRecord.objects.raw(raw_query)
推荐阅读
- azure - API“订阅 - 创建” - 需要哪个范围?
- flutter - 如何在运行时对 Flame (Flutter) 中精灵的渲染顺序进行排序?
- testing - 如何在 TFS 中编辑测试用例
- jenkins - 如何从标签链接作业中读取数据| 使用 groovy 脚本的 Jenkins 插件
- c# - 后台任务 - 即使应用程序已停止,如何在 .net Web 应用程序上运行后台任务?
- ios - 如何获取具有最高 Int 的变量并检索 String Swift
- html - HTML 选择一个 zip 文件或多个其他文件
- java - 错误:更新到 Android Studio 北极狐后,在视图中找不到符号导入 android.widget.set | 2020.3.1 补丁 2
- java - 百里香中的标签库
- vue.js - 在渲染期间访问了属性“dynamicslotname”,但未在实例上定义