【问题标题】:Django - get the newest record for each query result [duplicate]Django - 获取每个查询结果的最新记录[重复]
【发布时间】:2016-01-29 23:15:20
【问题描述】:

我不确定这是否可以在单个查询中完成。我有一个看起来像这样的模型:

class TestStatus(models.Model):
    id = models.AutoField(primary_key=True)
    build = models.CharField(max_length=20)
    test_name = models.CharField(max_length=50)
    test_status = models.CharField(max_length=10)
    test_start = models.DateTimeField(auto_now=True)
    test_end = models.DateTimeField(null=True)

该表旨在存储针对给定内部版本号的自动化测试运行结果。我想要做的是查询所有测试及其状态针对给定构建运行,但在某些情况下,相同的测试运行不止一次。此查询返回给定构建的所有测试:

TestStatus.objects.filter(build__exact='1.2.3.4')

但如果多次运行相同的测试,我会得到如下结果:

-------------------------------------------------
| test_name | test_status | test_start          |
-------------------------------------------------
| Test1     | FAIL        | 2015-10-28 14:20:56 |
| Test2     | PASS        | 2015-10-28 14:23:14 |
| Test1     | PASS        | 2015-10-28 15:21:24 |
-------------------------------------------------

我想要返回的只是针对给定build 运行的每个test_name 的最新test_status。我知道我可以在test_start 字段上执行MAX(),但它只返回一个条目,因为它正在查看查询集中所有字段的最大日期值。我可以做一个查询,然后如果有任何失败的测试做另一个查询,看看是否有给定的test_name 的新测试条目,但如果可以的话,我宁愿避免做多个查询。

我希望通过单个查询获得这样的输出:

-------------------------------------------------
| test_name | test_status | test_start          |
-------------------------------------------------
| Test2     | PASS        | 2015-10-28 14:23:14 |
| Test1     | PASS        | 2015-10-28 15:21:24 |
-------------------------------------------------

我只针对给定的构建运行最新的测试。有什么想法吗?

编辑

以下是我尝试过的一些其他事情(第一个由另一个答案建议): TestStatus.objects.annotate(max_date=Max('test_start')).filter(test_start=F('max_date'), build='1.2.3.4')

但这会返回与 TestStatus.objects.filter(build='1.2.3.4') 相同的结果

我也一直在使用其他答案中发布的一些 SQL,但是当我尝试按 build 过滤时,这个查询(这似乎可以解决我的问题)没有返回任何内容:

SELECT a.*
FROM test_status a
INNER JOIN(
    SELECT test_name, MAX(test_start) AS max_date
    FROM test_status
    GROUP BY test_name) b
ON a.test_name = b.test_name
AND a.test_start = b.max_date
WHERE build = '1.2.3.4';

【问题讨论】:

  • 你的意思是:TestStatus.object.filter(build__exact='1.2.3.4').latest('test_start')
  • 只返回给定查询中的最新记录(即只有一条记录),但我想查看查询集中所有记录的最新记录。
  • 仅供参考,您无需将 id 定义为自动字段...django does that for you.
  • @stimko68 检查latest QuerySet 运算符。

标签: python mysql django


【解决方案1】:

尝试:

tests = TestStatus.objects.filter(build__iexact='1.2.3.4',test_status=True).order_by('test_name','-test_start').distinct('test_name')

更新:刚刚看到mysql标签,distinct([*fields])只适用于PostgresSQL

【讨论】:

  • 这不考虑 build 值,这是我需要过滤的,因为我只关心特定 build 的结果
  • @stimko68 我已经编辑了我的答案。
  • 谢谢,但该查询没有返回任何结果
  • 这不适用于 MySQL。
猜你喜欢
  • 2021-01-10
  • 2020-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多