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