2013-08-07 4 views
7

Возможно ли воспроизвести следующий mysql-запрос в Django без использования метода select?Группа Django по датам и значениям SUM

MariaDB [db1]> SELECT datetime, SUM(datas) FROM table AND datetime BETWEEN '2013-07-26 13:00:00' AND '2013-07-26 23:00:00' GROUP BY datetime; 

Чтобы получить этот вид результата:

+---------------------+-----------+ 
| datetime   | SUM(data) | 
+---------------------+-----------+ 
| 2013-07-26 13:00:00 |  489 | 
| 2013-07-26 14:00:00 |  2923 | 
| 2013-07-26 15:00:00 |  984 | 
| 2013-07-26 16:00:00 |  2795 | 
| 2013-07-26 17:00:00 |  1308 | 
| 2013-07-26 18:00:00 |  1365 | 
| 2013-07-26 19:00:00 |  1331 | 
| 2013-07-26 20:00:00 |  914 | 
| 2013-07-26 21:00:00 |  919 | 
| 2013-07-26 22:00:00 |  722 | 
| 2013-07-26 23:00:00 |  731 | 
+---------------------+-----------+ 
11 rows in set (1.45 sec) 

Edit: я получил на текущий момент такого запроса:

>>> value = table.objects.filter(datetime__range=('2013-07-26 13:00:00', 
'2013-07-26 23:00:00')).values('datetime', 'data').annotate(Sum('data')) 

>>> print value.query 
SELECT `table`.`datetime`, `table`.`data` SUM(`table`.`imps`) AS `data__sum` 
FROM `table` 
WHERE `table`.`datetime` BETWEEN 2013-07-26 13:00:00 
and 2013-07-26 23:00:00 GROUP BY `table`.`datetime`, 
`table`.`data` ORDER BY NULL 

Почему сумма работать как на DateTime и данных?

Я пытался повсюду на django doc, здесь, на стеке, но не нашел чего-то связанного с моей проблемой. Любое предложение?

+1

Что SQL делает создать свой QuerySet? Вы можете использовать 'print values.query' –

+0

Переключить порядок' .annotate() 'и' .values ​​() ' –

ответ

6

Хмм вы используете Count, вы должны использовать Sum и values() будет определять, что происходит в GROUP BY, так что вы должны использовать только values('datetime'). Ваше QuerySet должно быть что-то вроде этого:

from django.db.models import Sum 

values = self.model.objects.filter(
    datetime__range=(self.dates[0], self.dates[1]) 
).values('datetime').annotate(data_sum=Sum('data')) 

хотя я не уверен, что о порядке filter(), так что это может быть так:

values = self.model.objects.values('datetime').annotate(data_sum=Sum('data')).filter(
    datetime__range=(self.dates[0], self.dates[1]) 
) 

Я думаю, вы бы хотите попробовать и тогда , Если вы хотите увидеть необработанный запрос из этих QuerySet, используйте Queryset.query:

print self.model.objects.filter(
    datetime__range=(self.dates[0], self.dates[1]) 
).values('datetime').annotate(data_sum=Sum('data')).query.__str__() 

Таким образом, вы можете убедиться, что вы получите правильный запрос.

Надеюсь, это поможет.

+1

thx, почему фильтр после аннотации? – tbenett

+1

Это просто я не уверен в их запросе, так что это может быть либо в любом случае использовать 'query .__ str __()' для проверки нужного вам запроса. Также внимательно проверьте мой ответ, вы должны использовать 'values ​​('datetime')' only –

+0

Можете ли вы отредактировать ответ, чтобы указать, какой ответ был правильным? – Jglstewart

4

order_by() поможет вам GROUP BY:

values = self.model.objects.filter(datetime__range=(
    self.dates[0], self.dates[1])) \ 
    .values('datetime') \ 
    .annotate(data_sum=Sum('datas') \ 
    .order_by()) 
+0

Не работает, извините: SELECT 'table'.'datetime',' table'.'data' FROM 'table' WHERE' table'.'datetime' BETWEEN 2013-07-26 13:00:00 и 2013-07 -26 23:00:00) ORDER BY 'table'.'datetime' ASC – tbenett

+0

Как насчет сейчас? –

+0

Хорошо, что я использую метод Hieu Nguyen, и проблема исходила из значений ('datetime', 'data') – tbenett