【问题标题】:Django ORM, group by dayDjango ORM,按天分组
【发布时间】:2012-04-26 14:36:06
【问题描述】:

我正在尝试按 DAY 对产品进行分组,但是 date_created 是一个日期时间字段。

Product.objects.values('date_created') \
               .annotate(available=Count('available_quantity'))

返回:

[
    {'date_created': datetime.datetime(2012, 4, 14, 13, 3, 6), 'available': 1},
    {'date_created': datetime.datetime(2012, 4, 14, 17, 12, 9), 'available': 1},
    ...
]

我想要:

[
    {'date_created': datetime.datetime(2012, 4, 14), 'available': 2}, ...
]

编辑:数据库后端 MYSQL

【问题讨论】:

  • 是的,我想要 [{'today': 17}、{'yesterday': 21} 等]

标签: python mysql django django-orm


【解决方案1】:

通过San4ez的回答和Zanon的变化

对我来说,我必须制定一个解决方法来使用 Postgres 或 Sqlite,因为 Count() 函数将考虑日期时间字段,如果你要创建一个仅包含日期的“日”输入并不重要,因为date_created 仍在保存时间信息,因此在尝试了许多不同的事情之后,我不会合并和计算多个带有时间的记录,我达到了跳过时间的方式

Django 2.2

from django.db.models import Count

# Change date() to to_char(created_at, 'YYYY-MM-DD') if using Postgres
Product.objects.extra(select={'day': 'date( date_created )'})\
    .values('day') \
    .order_by('date_created__date')\
    .annotate(available=Count('date_created__date'))

【讨论】:

    【解决方案2】:

    受this question 启发,在 MySQL 上试试这个

    from django.db.models import Count
    
    Product.objects.extra(select={'day': 'date( date_created )'}).values('day') \
                   .annotate(available=Count('date_created'))
    

    【讨论】:

    • 这很有帮助,但我必须在 values() 和 annotate() 之间使用明确的 order_by() 清除默认排序。见docs.djangoproject.com/en/dev/topics/db/aggregation/…。谢谢!
    • 奇怪...即使日期相同,我仍然有多个字段未分组在计数中...我尝试使用 to_char 解决方案并将我的数据库从 sqlite 更改为 postgres,但是当运行 available=Count('date_created') 他正在考虑日期时间
    【解决方案3】:

    你可以试试

    Product.objects.extra(select={'day': "TO_CHAR(date_created, 'YYYY-MM-DD')"})\
                    .values('day')\
                    .order_by('day')\
                    .annotate(bets=Count('date_created'))
    

    【讨论】:

      【解决方案4】:

      与San4ez 的回答类似,但将日期返回为 'YYYY-MM-DD' 而不是 'datetime.datetime(YYYY, MM, DD)':

      Product.objects.extra(select={'day': "TO_CHAR(date_created, 'YYYY-MM-DD')"})
                     .values('day') \
                     .order_by('day') \
                     .annotate(available=Count('date_created'))
      

      【讨论】:

      • 返回的查询集在您的答案中采用更易读的格式。谢谢。这比@San4ez 建议的要好
      【解决方案5】:

      在 Django 1.4 中,您可以使用 .dates('date_created', 'day') 代替 .values()。

      试试这个代码 sn-p:

      Product.objects.annotate(available=Count('available_quantity')) \
        .dates('date_created', 'day')
      

      这应该返回:

      [
          {'date_created': datetime.datetime(2012, 4, 14), 'available': 2}, ...
      ]
      

      【讨论】:

      • 听起来很接近,但我得到一个仅包含日期的列表:[datetime.datetime(2012, 4, 10, 0, 0), datetime.datetime(2012, 4, 10, 0, 0), datetime.datetime(2012, 4, 10, 0, 0), datetime.datetime(2012, 4, 10, 0, 0)]
      • 在使用 .dates 创建 DateQuerySet 之前尝试 .annotate()。
      • 对我来说也一样,只有日期
      猜你喜欢
      • 2017-03-30
      • 2018-03-10
      • 2011-10-19
      • 2016-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-17
      相关资源
      最近更新 更多