我有一个使用子查询中的值的查询。虽然我可以在 django 中编写子查询,但无法编写主查询。这是一个小例子(模式是 department <-- person <-- device --> model):
SELECT
department.id,
AVG(subquery.typeofdevices_count) AS avg_typeofdevice_count_per_department
FROM department
INNER JOIN person ON (department.id = person.department_id)
INNER JOIN device ON (person.id = device.person_id)
INNER JOIN (
SELECT
model.id AS id,
count(DISTINCT device.id) filter (WHERE device.type = 'something') AS typeofdevices_count,
FROM model
LEFT OUTER JOIN device ON (model.id = device.model_id)
WHERE ('some-conditions...')
GROUP BY model.id,
) AS subquery ON (subquery.id = device.model_id)
如您所见,外部查询使用内部值typeofdevices_count,同时与子查询id连接。
关于内部查询非常简单:
subquery = Model.objects.annotate(typeofdevices_count=
Count('device__location_id',
filter=Q(device__type='something'),
distinct=True
)
).filter('some-conditions...').values('id', 'typeofdevices_count')
主要查询怎么样?我尝试了以下方法:
Department.objects.annotate(avg_typeofdevice_count_per_department=
Avg('persons__devices__model__typeofdevices_count',
filter=Q(persons__devices__model__in=subquery)
)
).values('id', 'avg_typeofdevice_count_per_department')
但是我得到了这个错误,它似乎无法识别子查询注释typeofdevices_count
FieldError:无法将关键字“typeofdevices_count”解析为字段。选项有:...
你能帮我吗?
如果不查看模型以及关系存在哪些外键,就很难告诉您任何信息。
根据您提供的内容:
department <-- person <-- device --> model
,这部分是错误的,您不能直接从Department
引用到persons
关系,在您的查询中:
Department.objects.annotate(avg_typeofdevice_count_per_department=
Avg('persons__devices__model__typeofdevices_count',
filter=Q(persons__devices__model__in=subquery)
)
).values('id', 'avg_typeofdevice_count_per_department')
此外,你的原始
SQL
并不完全正确,但从中可以清楚地看出你想做什么。这是这样的,可以给出用 django ORM
写的预期结果:
from django.db import models
subquery = (
Device.objects
.select_related('model')
.filter(
# device.person_id=person.id
person_id=models.OuterRef('id'),
# and other conditions
)
# group by model.id
.values('model__id')
.annotate(
typeofdevices_count=models.Count(
'id',
filter=models.Q(type='something'),
distinct=True,
),
)
.values('typeofdevices_count')
)
queryset = (
Person.objects
.select_related('department')
.annotate(devices_count=models.Subquery(subquery))
.values('department__id')
.annotate(avg_typeofdevice_count_per_department=models.F('devices_count'))
.values('department__id', 'avg_typeofdevice_count_per_department')
)
我可能在某个地方犯了错误。你应该检查一下!它将生成与您的
SQL
略有不同的查询,但结果应该符合预期 - 每个部门计算某种类型设备的平均值。