Django:选择具有最大时间戳记的值或加入同一张表
问题内容:
我有一个简单的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方法添加到服务器模型,该方法将返回当前服务器的所有最后一个属性。我的意思是,它应返回当前服务器的所有属性名称的名称和值,并且每个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解决方案。请你帮助我好吗。
问题答案:
如果您使用的是PostgreSQL,通常的语法是:
select distinct on (name)
name, value
from environments_serverpropertie
where server = ...
order by name, timestamp desc
SELECT DISTINCT ON(expression [,…])仅保留给定表达式等于的每组行的第一行。使用与ORDER
BY相同的规则来解释DISTINCT ON表达式(请参见上文)。请注意,除非使用ORDER
BY来确保所需的行首先出现,否则每个集合的“第一行”都是不可预测的。
您可以在中查看并尝试 sql fiddle demo
。
可以从django文档中将此语法转换为django
:
仅在PostgreSQL上,您可以传递位置参数(* fields)来指定DISTINCT应该应用的字段名称。这将转换为SELECT DISTINCT
ON SQL查询。
因此在django中,它将类似于:
ServerPropertie.objects.filter(...).order_by('name', '-timestamp').distinct('name')