Django 分组查询?
Django Group by query?
我正在使用 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 注释函数来实现这个 - 这是 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')
在调试时,我发现 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") ) 字段,尽管我在 y Django ORM 查询中没有提到任何地方。因此,输出将发生变化。
默认情况下,Django ORM 是否考虑了 id 字段?
有什么办法可以解决吗?
试试这个
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')
可以通过 -
修复
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 需要 return id(primary_key) 字段 .
我正在使用 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 注释函数来实现这个 - 这是 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')
在调试时,我发现 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") ) 字段,尽管我在 y Django ORM 查询中没有提到任何地方。因此,输出将发生变化。
默认情况下,Django ORM 是否考虑了 id 字段? 有什么办法可以解决吗?
试试这个
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')
可以通过 -
修复 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 需要 return id(primary_key) 字段 .