【问题标题】:Django queryset with extra()带有额外()的Django查询集
【发布时间】:2015-01-05 08:44:13
【问题描述】:

我有四个模型

class Group(models.Model):
    pass

class Item(models.Model):
    group = ForeignKey(Group)

class ItemRevision(models.Model):
    item = ForeignKey(Item)
    date = DateField()

class ItemRevisionMonth(models.Model):
    item_revision = ForeignKey(ItemRevision)
    year = PositiveSmallIntegerField()
    amount = IntegerField()

我正在尝试在 Django 中进行相当复杂的 sql 查询,所以我认为 Django ORM 无法处理它。

我需要打印所有组并用金额总和 SUM(amount) 对每个组进行注释。除此之外,它应该只选择 1 ItemRevision(最新添加的)。

我认为是这样的:

Group.objects.all().extra(select={
    SELECT SUM(amount) FROM app_itemrevisionmonth LEFT JOIN app_itemrevision ON item_revision_id = app_itemrevision.id WHERE item_id = app_item.id AND app_item.group_id = app_group.id
})

但我不知道如何判断只能从最新版本中选择。

编辑 1

可能是这样的:

SELECT
    SUM(amount)
FROM
    app_itemrevisionmonth
LEFT JOIN
    (
      SELECT
          id
      FROM
          app_itemrevision
      WHERE
          date < %s
      LIMIT
          1
    )
ON
    item_revision_id = app_itemrevision.id
WHERE
    item_id = app_item.id AND
    app_item.group_id = app_group.id

编辑 2

结构将是

"id": 1,
"items": [
    {
        "id": 1
        "revisions": [
            {
                "id": 1, 
                "date": "01-10-2014", 
                "months": [
                    {
                        "year": 2014, 
                        "amount": "2321"
                    }, 
                    {
                        "year": 2014,  
                        "amount": "500"
                    }, 
                    {
                        "year": 2014,  
                        "amount": "500"
                    }, 
                    {
                        "year": 2014,  
                        "amount": "500"
                    }, 
                ]
            }
        ]
    },
]

一个项目可能有多个修订版,在这种情况下,它应该只使用最新的修订版并忽略其他修订版。除此之外,应该可以在特定日期之前使用修订。

【问题讨论】:

  • 我觉得不行:WHERE item_id = app_item.id AND

标签: python mysql sql django sqlite


【解决方案1】:

尝试注释

Group.objects.all().annotate(
    sum=models.Sum('item_set__itemrevision_set__itemrevisionmonth_set__amount')
)

详情:https://docs.djangoproject.com/en/dev/topics/db/queries/#backwards-related-objects

【讨论】:

  • 我不认为我可以使用注释,因为我希望能够选择不同的修订。我真的需要像 SUMIF 之类的东西 :-) 但如果我可以选择修订版为 ItemRevision.objects.filter(date_lte=??).latest() 就完美了,这样可以选择查看特定日期之前的数据。
  • 模型ItemRevision 中没有date 字段。你能重构一个例子吗?
猜你喜欢
  • 1970-01-01
  • 2012-07-05
  • 2019-03-15
  • 1970-01-01
  • 2016-02-21
  • 2018-07-06
  • 1970-01-01
  • 2016-09-15
  • 2013-02-12
相关资源
最近更新 更多