【问题标题】:Django Queries: related subqueryDjango 查询:相关子查询
【发布时间】:2014-09-04 21:48:19
【问题描述】:

我有 3 个模型:Offer、Request 和 Assignment。分配在请求和报价之间建立了联系。现在我想这样做:

select *
from offer as a
where places > (
    select count(*)
    from assignment
    where offer_id = a.id and
    to_date > "2014-07-07");

我不确定如何使用 django QuerySet 来实现这一点...有什么提示吗?

编辑:上面的查询只是一个示例,查询一般应该是什么样子。 django 模型如下所示:

class Offer(models.Model):
    ...
    places = models.IntegerField()
    ...

class Request(models.Model):
    ...

class Assignment(models.Model):
    from_date = models.DateField()
    to_data = models.DateField()
    request = models.ForeignKey("Request",related_name="assignments")
    offer = models.ForeignKey("Offer",related_name="assignments")

人们现在可以创建具有给定数量的位置或请求的要约。然后,管理员将在给定时间内将请求与报价联系起来。这被保存为作业。上面的查询应该给我一个报价列表,其中还有位置。因此,我想计算给定报价的有效分配数量,以将其与其位置数量进行比较。此列表应用于为给定的创建新作业的请求查找可能的报价。

我希望这能更好地描述问题。

【问题讨论】:

  • offer request和assignment与这三个的model字段有什么关系?
  • 我添加了详细的解释。

标签: sql django subquery django-queryset


【解决方案1】:

不幸的是,ORM 操作不直接支持相关的子查询。在这种情况下应该可以使用.extra(where=...)

要在不使用子查询的情况下获得相同的结果,应该可以使用以下方法:

Offer.objects.filter(
    assignment__to_date__gt=thedate
).annotate(
    assignment_cnt=Count('assignment')
).filter(
    assignment_cnt__lte=F('places')
) 

确切的查询取决于模型定义。

【讨论】:

  • 第二种方法产生一个OUTER JOIN 查询,因此比任何涉及子查询的方法都更有效。鉴于此方法还避免了 rawextra 调用中的任何原始 sql,因此此方法绝对是实现预期结果的首选方法。
【解决方案2】:
query = '''select *
from yourapp_offer as a
where places > (
    select count(*)
    from yourapp_assignment
    where offer_id = a.id and
    to_date > "2014-07-07");'''

offers = Offer.objects.raw(query):

https://docs.djangoproject.com/en/1.6/topics/db/sql/

【讨论】:

  • 为什么是-1?这是做到这一点的唯一方式(((:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
  • 2015-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-20
相关资源
最近更新 更多