Django self join,如何将此查询转换为ORM查询

时间:2014-10-30 12:45:36

标签: python mysql django django-orm

如何将此查询转换为django ORM查询。

select T.node_id, ht, status, data from (
select id, Max(health_time) as ht, node_id from remote_sense_nodehealth group by node_id
) as T
join remote_sense_nodehealth on remote_sense_nodehealth.health_time=T.ht and remote_sense_nodehealth.node_id = T.node_id

实际上我想根据其他列值获取所有最新值。

例如我的表就像 -

c1 | c2  | c3 
- - - - - - -
x | 1 AM | d1
x | 2 AM | d2
x | 3 AM | d3
y | 1 AM | d4
y | 2 AM | d5{

期望的输出:

[{c1:x,c2:3AM,c3:d3},{c1:y,c2:2AM,c3:d5}]

2 个答案:

答案 0 :(得分:1)

使用更规范化的数据模型,您可以更轻松地完成此操作。考虑使用这样的方法:

class NodeGroup(model.Model):
    pass

class NodeHealth(model.Model):
    node_group = models.ForeignKey(NodeGroup, related_name='nodes')
    health_time = models.IntegerField()
    status = models.IntegerField()

然后你可以这样做:

from django.db.models import Max, F

nodes = NodeHealth.objects.all().annotate(
    max_health_time=Max('node_group__nodes__health_time')
).filter(health_time=F('max_health_time'))

不幸的是,在此时,如果多个节点具有health_time的相同值,则返回的节点将具有重复项。您可以添加一个可以清除它的.distinct('node_group_id'),但我并非100%正面。

答案 1 :(得分:0)

如果您的数据库支持分析,您可以执行以下操作:

q = NodeHealth.objects.extra(
    select={'row_num': "ROW_NUMBER() OVER (PARTITION BY c1 ORDER BY c2 DESC)"},
    where=["row_num=1"]
)