如果 values() 子句在 annotate() 之前,就会根据 values() 子句产生的分组来计算注解。
然而如果 annotate() 子句在 values() 之前,就会根据整个查询集生成注解。这种情况下,values() 子句只能限制输出的字段。
计算所有的项目中引入名字是poi的组件,版本与数量分布情况
Component.objects.filter(name='poi').\
values('version').\
annotate(software_count=Count('sboms__software',
distinct=True))
输出
<QuerySet [
{'version': '3.10', 'software_count': 1},
{'version': '3.8', 'software_count': 7},
{'version': '3.9', 'software_count': 2}]>
查看上面语句实际执行的SQL语句
print(Component.objects.filter(name='poi').\
values('version').\
annotate(software_count=Count('sboms__software', distinct=True)).\
query)
SELECT
` sbom_manager_component `.` version `,
COUNT(DISTINCT ` sbom_manager_sbom `.` software_id `) AS ` software_count `
FROM
` sbom_manager_component `
LEFT OUTER JOIN ` sbom_manager_sbom_components ` ON (
` sbom_manager_component `.` id ` = ` sbom_manager_sbom_components `.` component_id `
)
LEFT OUTER JOIN ` sbom_manager_sbom ` ON (
` sbom_manager_sbom_components `.` sbom_id ` = ` sbom_manager_sbom `.` id `
)
WHERE
` sbom_manager_component `.` name ` = poi
GROUP BY
` sbom_manager_component `.` version `
ORDER BY
NULL
Component.objects.all().aggregate(Avg('pk'))
实际执行的SQL语句
SELECT
AVG(` sbom_manager_component `.` id `) AS ` pk__avg `
FROM
` sbom_manager_component `
查看每个组件,对应的SBOM的数量
Component.objects.annotate(Count('sboms'))
SELECT
` sbom_manager_component `.` id `,
` sbom_manager_component `.` name `,
` sbom_manager_component `.` vendor `,
` sbom_manager_component `.` version `,
` sbom_manager_component `.` type `,
COUNT(` sbom_manager_sbom_components `.` sbom_id `) AS ` sboms__count `
FROM
` sbom_manager_component `
LEFT OUTER JOIN ` sbom_manager_sbom_components ` ON (
` sbom_manager_component `.` id ` = ` sbom_manager_sbom_components `.` component_id `
)
GROUP BY
` sbom_manager_component `.` id `
ORDER BY
NULL
使用 values() 子句来对结果集进行约束