Subquery 在Django子查询中,我可以引用;“家长”;查询

Subquery 在Django子查询中,我可以引用;“家长”;查询,subquery,where,django-orm,Subquery,Where,Django Orm,在Django ORM中创建子查询很简单(只需在另一个查询中使用QuerySet),但该子查询是否可以引用“父”(外部,主)查询中的字段 有关我试图实现的目标的完整示例,请参见此操作。我把它分解成两个问题()。在本例中,我有一个表示必须达到的值的模型整数。有几个零件贡献了它们自己的(计算)值。我想检索所有尚未完成的整体s(即总值不同于单个值的总和) 我不知道如何(或者是否可能)使用Django ORM实现这一点。我在中看到过使用\uu的子查询(并且可以通过print qs.query确认结果确实

在Django ORM中创建子查询很简单(只需在另一个查询中使用
QuerySet
),但该子查询是否可以引用“父”(外部,主)查询中的字段

有关我试图实现的目标的完整示例,请参见此操作。我把它分解成两个问题()。在本例中,我有一个表示必须达到的值的模型
整数。有几个
零件
贡献了它们自己的(计算)值。我想检索所有
尚未完成的
整体
s(即
总值
不同于单个值的总和)

我不知道如何(或者是否可能)使用Django ORM实现这一点。我在
中看到过使用
\uu的子查询(并且可以通过
print qs.query
确认结果确实是作为单个查询运行的),但仅当两个查询彼此独立时。在这里,子查询受父查询中的字段约束(
w.id
)。我曾想过使用
F()
Q()
,甚至
extra
,但不知道该怎么办

这里有一个SSCCE,以防有人想用它做实验:或者。它与上面链接的模型和数据相同


更新:对于我的特殊情况,我发现不需要进行子查询,我可以使用
分组依据
拥有
(如图所示):


但是子查询的一般情况仍然没有解决(除了使用一些原始SQL,如图所示)。

我用最少原始SQL设计的解决方案使用了
额外的
,其中

qs = Whole.objects.extra(where=['total_value != ({})'.format(qs1.query)])
  • 首先创建内部查询;使用
    extra
    指定一个自定义
    where
    组件,将受限字段与外部查询中出现的字段进行比较(可能需要硬编码表名/别名):

    然后对其执行其余操作(在本例中,使用
    注释
    对单个字段进行分组、聚合和返回)

  • 然后在外部查询中包括内部查询生成的SQL(使用
    .query
    ),也使用
    extra
    其中

    qs = Whole.objects.extra(where=['total_value != ({})'.format(qs1.query)])
    
额外
调用中的代码片段可能不可移植(例如:某些后端使用
!=
,其他后端使用
,引用表名的正确方式可能会有所不同,等等),但内部查询的其余部分应该是可移植的(因为它是由ORM生成的)

生成的查询对应于我要查找的内容(中介绍的聚合部分除外)。SQL格式化以确保可读性:

>>> qs1 = Part.objects.extra(
        where=['whole_id = "aggregation_subquery_whole"."id"']
    ).values('whole_id').annotate(sum=Sum('before__value')).values('sum')

>>> qs = Whole.objects.extra(where=['total_value != ({})'.format(qs1.query)])

>>> print qs.query

SELECT "aggregation_subquery_whole"."id",
       "aggregation_subquery_whole"."total_value" 
FROM "aggregation_subquery_whole"
WHERE total_value != (
    SELECT SUM("aggregation_subquery_sequence"."value") AS "sum"
    FROM "aggregation_subquery_part"
        LEFT OUTER JOIN "aggregation_subquery_sequence" ON
           ("aggregation_subquery_part"."before_id" =
            "aggregation_subquery_sequence"."id") 
    WHERE whole_id = "aggregation_subquery_whole"."id"
    GROUP BY "aggregation_subquery_part"."whole_id"
)

Django(从Django 1.11开始)提供了对相关子查询的完全支持,包括对外部查询的引用。
qs = Whole.objects.extra(where=['total_value != ({})'.format(qs1.query)])
>>> qs1 = Part.objects.extra(
        where=['whole_id = "aggregation_subquery_whole"."id"']
    ).values('whole_id').annotate(sum=Sum('before__value')).values('sum')

>>> qs = Whole.objects.extra(where=['total_value != ({})'.format(qs1.query)])

>>> print qs.query

SELECT "aggregation_subquery_whole"."id",
       "aggregation_subquery_whole"."total_value" 
FROM "aggregation_subquery_whole"
WHERE total_value != (
    SELECT SUM("aggregation_subquery_sequence"."value") AS "sum"
    FROM "aggregation_subquery_part"
        LEFT OUTER JOIN "aggregation_subquery_sequence" ON
           ("aggregation_subquery_part"."before_id" =
            "aggregation_subquery_sequence"."id") 
    WHERE whole_id = "aggregation_subquery_whole"."id"
    GROUP BY "aggregation_subquery_part"."whole_id"
)