我不确定这是否可以在单个查询中完成。我的模型看起来像这样:
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 |
-------------------------------------------------
我想要返回的内容仅是针对给定test_status
的每次test_name
投放的最新build
。我知道我可以在MAX()
字段上执行test_start
但只返回一个条目,因为它查看了查询集中所有字段的最大日期值。我可以进行查询,然后如果有任何失败的测试,则执行另一个查询以查看给定的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';
答案 0 :(得分:0)
尝试:
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