如何在查找中包含一列,但在GROUP BY中排除它?

4 投票
1 回答
1239 浏览
提问于 2025-04-16 22:23

我正在尝试使用Django的ORM执行以下查询:

SELECT object_repr, content_type_id, COUNT(object_repr) 
FROM django_admin_log GROUP BY object_repr ORDER BY COUNT(object_repr);

我目前得到的结果是:

LogEntry.objects.values('object_repr', 'content_type__id')\
                .annotate(num_logs=Count('object_repr'))\
                .order_by('num_logs')

不幸的是,这个结果生成的SQL语句返回了错误的(或者说,至少是意料之外的)结果:

SELECT `django_admin_log`.`object_repr`, `django_admin_log`.`content_type_id`, 
COUNT(`django_admin_log`.`object_repr`) AS `num_logs` 
FROM `django_admin_log` 
GROUP BY `django_admin_log`.`object_repr`, `django_admin_log`.`content_type_id` 
ORDER BY num_logs

values()方法会把所有指定的列都放进“GROUP BY”部分,但我不想在我的GROUP BY中包含content_type_id。在ORM中真的可以做到这一点吗?

补充:结果发现,在ORM中这是不可能的。不过为了将来有需要的人能找到这个问题,我写的查询可以满足我的需求是:

SELECT DISTINCT djl2.id, djl1.object_id, djl1.object_repr,
                         djl1.content_type_id,
                         COUNT(djl1.content_type_id) AS num_items
FROM django_admin_log AS djl1
    INNER JOIN django_admin_log AS djl2
    ON djl1.id=djl2.id
GROUP BY djl1.object_repr, djl1.content_type_id
ORDER BY num_items

基本上是一个自连接。祝你好运,希望这能帮到你。

1 个回答

3

我最近几天也遇到了这个问题,虽然我发的问题没有你写得那么好。

不过,我发现虽然 Sqlite 和 MySql 在你执行一个查询时,如果选择了不在 group by 子句中的列,它们不会报错,但这些结果可能不太可靠,因为 SQL 的标准似乎是不允许这样做。我知道 MSSQL 在你尝试这样做时会返回错误,但我不太确定其他类型的 SQL 是不是也是这样。

基于这个,我得出结论,django 不允许通过 ORM 生成这样的查询,因为从技术上讲,这并不合法,尽管在某些 SQL 类型上可能在某种程度上能工作。

这里是我问题的链接,供参考: 我可以控制 django 1.3 的 ORM 中的 GROUP BY 吗?

撰写回答