Django:选择具有最大时间戳的值或连接到同一个表

时间:2013-08-25 20:24:07

标签: python sql django postgresql

我有一个简单的Django模型

class Server(models.Model):
    name = models.CharField(max_length=120)

class ServerPropertie(models.Model):
    name = models.CharField(max_length=120)
    value = models.CharField(max_length=120)
    timestamp = models.DateTimeField()
    server = models.ForeignKey(Server)

我想将get_properties方法添加到Server模型,该模型将返回当前服务器的所有最后属性。我的意思是它应该返回当前服务器的所有属性名称的名称和值,并且每个uniq属性名称都应该有一个值,该行具有最大时间戳。

我可以在原始硬编码的原始SQL中使用它(我使用postgres):

SELECT t1.name, t1.value FROM environments_serverpropertie t1
JOIN (SELECT max("timestamp") "timestamp", name 
      FROM environments_serverpropertie
      group by name) t2 on t1.name = t2.name and t1.timestamp = t2.timestamp;

或在python中,但我相信存在pythonic解决方案。你能帮我吗?

1 个答案:

答案 0 :(得分:6)

如果您使用的是PostgreSQL,通常的语法是:

select distinct on (name)
    name, value
from environments_serverpropertie
where server = ...
order by name, timestamp desc

来自PostgreSQL documentation

  

SELECT DISTINCT ON(表达式[,...])仅保留第一行   给定表达式求值等于的每组行。该   DISTINCT ON表达式使用与之相同的规则进行解释   ORDER BY(见上文)。请注意,每组的“第一行”是   不可预测,除非使用ORDER BY来确保所需的行   首先出现。

您可以在sql fiddle demo中查看并试用它。

可以将此语法翻译为django,来自django documentation

  

仅在PostgreSQL上,您可以传递位置参数(*字段)   命令指定DISTINCT应该应该的字段的名称   应用。这转换为SELECT DISTINCT ON SQL查询。

所以在django中它会是这样的:

ServerPropertie.objects.filter(...).order_by('name', '-timestamp').distinct('name')