V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
hunk
V2EX  ›  Python

django 中如何进行分组统计?

  •  
  •   hunk · 2018-06-27 16:50:16 +08:00 · 7271 次点击
    这是一个创建于 2340 天前的主题,其中的信息可能已经有所发展或是发生改变。

    model 结构是 id,add_date,car_id,service_item car_id 是外键。

    Service.objects.annotate(car_count=Count('car_id')) 想按 car_id 进行分组统计,但结果是一条记录一行。似乎是受日期字段的影响。 纯 sql 好解决,在 model 的范围内,怎么处理?

    12 条回复    2022-01-20 16:25:44 +08:00
    746970179
        1
    746970179  
       2018-06-27 17:21:13 +08:00
    如果是想统计每个 car_id 有多少个 service, 即按照 car_id 进行 group by
    那么 Service.objects.values('car_id').annotate(car_count=Count('car_id')) 即可

    你可以在每条 queryset 后面, 用.query 看对应 queryset 的 sql 语句
    Service.objects.values('car_id').annotate(car_count=Count('car_id')).query
    大致就是 select car_id, count('car_id') from service group by car_id.
    hunk
        2
    hunk  
    OP
       2018-06-27 17:36:43 +08:00
    这样的结果是正确的,只是未能选出其它字段,如 service_item 和 add_date,如何同时选出统计结果和其它字段?
    hunk
        3
    hunk  
    OP
       2018-06-27 17:38:37 +08:00
    values 中一旦添加其它字段,统计结果就为 1,完全没分组。
    model 感觉不如 sql 来的直接。
    aixia0124
        4
    aixia0124  
       2018-06-27 18:16:24 +08:00
    分组聚类计算用 annotate,如果你的 model.META 里定义了 ordering 属性,需要在 annotate 之后 order_by()一下。
    应该就不会出现你说的聚类受日期影响了
    746970179
        5
    746970179  
       2018-06-27 18:40:51 +08:00
    car_id 和 service 是一对多的关系, 所以你取出来的时候, 到底取哪个 add_date 呢?

    values 里的字段, 在这里是 group by 里的字段.
    group by 多个字段, 自然数量大多是 1 了.
    hunk
        6
    hunk  
    OP
       2018-06-27 19:14:11 +08:00
    @746970179 是否是说,不能同时取出表内其它字段和统计结果,只能取到聚合字段和统计值?
    先取出字段信息,再计算统计结果,如何进行关联并显示呢?
    thread2
        7
    thread2  
       2018-06-27 19:29:50 +08:00
    “纯 sql 好解决”,“ model 感觉不如 sql 来的直接”,你想要的 SQL 怎么写的?
    tomczhen
        8
    tomczhen  
       2018-06-27 19:43:10 +08:00 via Android
    1 .用物化(索引)视图实现,模型绑定视图。
    2. 通过模型获取需要的数据,应用内分组汇总。
    xpresslink
        9
    xpresslink  
       2018-06-27 23:12:14 +08:00
    楼主注意,annotate 有个坑
    如果你的 Model 定义了默认排序字段, 必须要加 order_by()

    Service.objects.values('car_id').annotate(car_count=Count('car_id')).order_by()
    georgema1982
        10
    georgema1982  
       2018-06-28 02:23:19 +08:00
    @xpresslink 这个不是 django 的 order by 的坑,而是数据库的坑。如果数据库遵守 sql 标准的话就存在这个所谓的“坑”(其实不是坑,而是标准),如果是 mysql 的话就会放你一马
    hunk
        11
    hunk  
    OP
       2018-06-28 08:00:10 +08:00
    谢谢楼上二位,问题是我没在 model 中加 order_by,稍后再研究下 annotate。

    现在在 model 定义了函数,返回 count。每一行一个二次查询。不雅,总算能解决问题。

    跨表统计这种情况,还是要小心研究下,以后只会多不会少。mongodb 中似乎也不方便。还是老老实实 mysql 吧。
    UN2758
        12
    UN2758  
       2022-01-20 16:25:44 +08:00
    @hunk #11 lz 我也遇到同样的问题了,除了二段查询有别的解决方法吗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2724 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 12:38 · PVG 20:38 · LAX 04:38 · JFK 07:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.