Django Group通过查询?

时间:2017-05-05 12:29:00

标签: python django postgresql django-models django-orm

我使用django ORM使用逐个查询来获取数据。 原始的postgresql查询是 -

select date_trunc('day', time) as Time ,count(status) from table where group_id='2177' and status=1 group by date_trunc('day', time) order by time desc limit 7 offset 0;

并返回正确的输出..

        time              | count 
---------------------------+-------
2017-05-04 00:00:00+05:30 |    12
2017-05-03 00:00:00+05:30 |    26
2017-05-02 00:00:00+05:30 |    25
2017-05-01 00:00:00+05:30 |    26
2017-04-30 00:00:00+05:30 |    26
2017-04-29 00:00:00+05:30 |    26
2017-04-28 00:00:00+05:30 |    26

(7行)

我正在使用django annotate函数来实现这一点 - 这里是django查询 -

  records = TableModel.objects.filter(                  
                       group_id=group_id,                                           
                       status=1,                                                                       
                       time__range = get_time_range(range)                                                                    
                       ).annotate(
                                  period=DateTrunc('day', 'time') ,
                                  count=Count('status')
                               ).annotate(
                                         period = DateTrunc('day', 'time')
                               ).order_by('-time')

在Debug上,我发现django在内部将其转换为 -

   SELECT "table"."id", "table"."time", "table"."status", "table"."group_id", DATE_TRUNC('day', "table"."time") AS "period", COUNT("table"."status") AS "count" FROM "table" WHERE ("table"."group_id" = '2177' AND "table"."status" = 1 AND "table"."time" BETWEEN '2017-04-28 11:47:21.421755+00:00' AND '2017-05-05 11:47:21.421755+00:00') GROUP BY "table"."id", DATE_TRUNC('day', "table"."time") ORDER BY "table"."time" DESC;

这是它的o / p(它包含更多行数) -

     id   |           time            | status               | group_id      |          period           | count 
  --------+---------------------------+----------------------+------------+---------------------------+-------
   267821 | 2017-05-04 10:36:13+05:30 |                    1 | 2177       | 2017-05-04 00:00:00+05:30 |     1
   267790 | 2017-05-04 09:36:35+05:30 |                    1 | 2177       | 2017-05-04 00:00:00+05:30 |     1
   267786 | 2017-05-04 09:30:44+05:30 |                    1 | 2177       | 2017-05-04 00:00:00+05:30 |     1
   267735 | 2017-05-04 08:36:09+05:30 |                    1 | 2177       | 2017-05-04 00:00:00+05:30 |     1
   267696 | 2017-05-04 07:36:32+05:30 |                    1 | 2177       | 2017-05-04 00:00:00+05:30 |     1
   267650 | 2017-05-04 06:36:14+05:30 |                    1 | 2177       | 2017-05-04 00:00:00+05:30 |     1
   267603 | 2017-05-04 05:36:14+05:30 |                    1 | 2177       | 2017-05-04 00:00:00+05:30 |     1

    ....
    ....
    (149 rows)

即默认情况下,它使用( id DATE_TRUNC(' day'," table"。" time&#)开始分组34;))字段虽然我在y Django ORM Query中没有提到。结果,输出将会改变。

Django ORM默认是否考虑了id字段? 有什么办法可以解决吗?

2 个答案:

答案 0 :(得分:0)

试试这个

TableModel.objects.filter(                  
       group_id=group_id,                                           
       status=1,                                                                       
       time__range = get_time_range(range)                                                                    
   ).annotate(
          period=DateTrunc('day', 'time') # Truncate to day and add to select query
   ).values('period') # Group By period
   .annotate(count=Count('status'))  # add count of the grouping to select
   .values('period', 'count') 
   .order_by('-time')

答案 1 :(得分:0)

可以通过 -

修复
  SELECT 1 as id ,DATE_TRUNC('day', "table"."time") AS "period", COUNT("table"."status") AS "count" FROM "table" WHERE "table"."group_id" = '2177' and "table"."status"=1 and time >= '2017-04-28 12:48:33.348682+00:00' and time <= '2017-05-05 12:48:33.348682+00:00' GROUP BY DATE_TRUNC('day', "table"."time"),period ORDER BY period DESC limit {} offset {};

默认情况下,django需要返回id(primary_key)字段。