栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

关于 annotate 运行与预想不符(group by 多一个字段)的问题

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

关于 annotate 运行与预想不符(group by 多一个字段)的问题

解决

由于在 model 中的 meta 添加了默认的 order_by,导致使用 annotate 时一直无法满足预期的结果,只需要添加空的 order_by 重置排序,或者删去默认排序即可。

过程

在 django 中,使用 anotate 来做分组查询。以下是对 annotate 的介绍以及为什么我会出现问题的描述。

假设我们有这么一张表 table1:

id用户名 username系统 system
1张三Windows
2李四Android
3王五IOS
4赵六Windows

如果我们要对统计有多少人在使用使用这些系统,只需要这么一小句 SQL 语句

select system, count(device) from table1 group by system;

输出如下:

+---------+---------------+
| device  | count(device) |
+---------+---------------+
| Android |             1 |
| IOS     |             1 |
| Windows |             2 |
+---------+---------------+

而在 django 中理论上只需要这样即可完成上述操作(假设 Table1 为模型类):

from django.db.models import Count

queryset = Table1.objects.values("device").annotate(Count("device"))

然而事实并不如我所愿,在语句执行之后,发现目标字段并没有进行分组,而是单独分开成了一个组,结果大概就像下面这样,所以 Count(“device”) 就变成了 1。

+---------+---------------+
| device  | count(device) |
+---------+---------------+
| Android |             1 |
| IOS     |             1 |
| Windows |             1 |
| Windows |             1 |
+---------+---------------+

将 queryset 的原始对象打印,发现该语句多了一个用于 group by 的字段,大概如下:

>>> print(queryset.query)
SELECt `table1`.`device`, COUNT(`table1`.`device`) FROM `table1` GROUP BY `table1`.`device`, `table1`.`create_time`

可以看到是 group by 之后多了 create_time 字段,这个字段是我在创建模型类的时候填写的默认排序,即 class meta 中的 ordering。在翻阅了不少东西过后,发现解决它就得从排序下手,要么删除默认排序,要么使用一个空的排序来重置它。于是上面的 django 代码可以改写成这样。

queryset = Table1.objects.values("device").annotate(Count("device")).order_by()

于是就这么正常了,至于空的 order_by,相当于 ORDER BY NULL。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/325957.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号